1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-08 17:54:40 +00:00

Refactored phi to use blocks instead of individual statements

This commit is contained in:
jespergravgaard 2017-07-23 23:29:40 +02:00
parent 122cef4e30
commit 300bb644b9
35 changed files with 1990 additions and 736 deletions

View File

@ -138,7 +138,7 @@ public class AsmFragment {
LabelRef destination = conditionalJump.getDestination();
ControlFlowBlock destinationBlock = graph.getBlock(destination);
String destinationLabel = destination.getFullName();
if (destinationBlock.hasPhiStatements()) {
if (destinationBlock.hasPhiBlock()) {
destinationLabel = (destinationBlock.getLabel().getLocalName() + "_from_" + block.getLabel().getLocalName()).replace('@', 'B').replace(':','_');
}
Symbol destSymbol = symbols.getSymbol(destination);

View File

@ -1,6 +1,7 @@
package dk.camelot64.kickc.icl;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.ArrayList;
@ -78,10 +79,6 @@ public class ControlFlowBlock {
return statements;
}
public void addPhiStatement(VariableVersion newVersion) {
statements.add(0, new StatementPhi(newVersion.getRef()));
}
public String getAsTypedString(ControlFlowGraph graph, ProgramScope scope) {
StringBuffer out = new StringBuffer();
out.append(label.getFullName() + ":" );
@ -134,15 +131,6 @@ public class ControlFlowBlock {
return out.toString();
}
public boolean hasPhiStatements() {
if(statements.size()>0) {
if(statements.get(0) instanceof StatementPhi) {
return true;
}
}
return false;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@ -168,4 +156,32 @@ public class ControlFlowBlock {
result = 31 * result + (callSuccessor != null ? callSuccessor.hashCode() : 0);
return result;
}
/**
* Get the phi block for the block. If the phi block has not yet been created it is created.
* @return
*/
@JsonIgnore
public StatementPhiBlock getPhiBlock() {
StatementPhiBlock phiBlock = null;
if(statements.size()>0 && statements.get(0) instanceof StatementPhiBlock) {
phiBlock = (StatementPhiBlock) statements.get(0);
}
if(phiBlock==null) {
phiBlock = new StatementPhiBlock();
statements.add(0, phiBlock);
}
return phiBlock;
}
public boolean hasPhiBlock() {
if(statements.size()>0) {
if(statements.get(0) instanceof StatementPhiBlock) {
return true;
}
}
return false;
}
}

View File

@ -29,10 +29,10 @@ public class ControlFlowGraphBaseVisitor<T> {
return visitJump((StatementJump) statement);
} else if(statement instanceof StatementLabel) {
return visitJumpTarget((StatementLabel) statement);
} else if(statement instanceof StatementPhi) {
return visitPhi((StatementPhi) statement);
} else if(statement instanceof StatementCall) {
return visitCall((StatementCall) statement);
} else if(statement instanceof StatementPhiBlock) {
return visitPhiBlock((StatementPhiBlock) statement);
} else if(statement instanceof StatementReturn) {
return visitReturn((StatementReturn) statement);
} else if(statement instanceof StatementProcedureBegin) {
@ -72,7 +72,7 @@ public class ControlFlowGraphBaseVisitor<T> {
return null;
}
public T visitPhi(StatementPhi phi) {
public T visitPhiBlock(StatementPhiBlock phi) {
return null;
}

View File

@ -114,13 +114,14 @@ public class ControlFlowGraphCopyVisitor extends ControlFlowGraphBaseVisitor<Obj
}
@Override
public StatementPhi visitPhi(StatementPhi phi) {
VariableRef lValue = phi.getlValue();
StatementPhi copyPhi = new StatementPhi(lValue);
for (StatementPhi.PreviousSymbol origPreviousVersion : phi.getPreviousVersions()) {
RValue rValue = origPreviousVersion.getrValue();
LabelRef block = origPreviousVersion.getBlock();
copyPhi.addPreviousVersion(block, rValue);
public StatementPhiBlock visitPhiBlock(StatementPhiBlock phi) {
StatementPhiBlock copyPhi = new StatementPhiBlock();
for (StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
VariableRef variable = phiVariable.getVariable();
StatementPhiBlock.PhiVariable copyVar = copyPhi.addPhiVariable(variable);
for (StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
copyVar.setrValue(phiRValue.getPredecessor(), phiRValue.getrValue());
}
}
return copyPhi;
}

View File

@ -11,7 +11,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type")
@JsonSubTypes({
@JsonSubTypes.Type(value = StatementAssignment.class, name = "assign"),
@JsonSubTypes.Type(value = StatementPhi.class, name = "phi"),
@JsonSubTypes.Type(value = StatementPhiBlock.class, name = "phiblock"),
@JsonSubTypes.Type(value = StatementConditionalJump.class, name = "cond"),
@JsonSubTypes.Type(value = StatementJump.class, name = "jump"),
@JsonSubTypes.Type(value = StatementLabel.class, name = "label"),

View File

@ -1,155 +0,0 @@
package dk.camelot64.kickc.icl;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.ArrayList;
import java.util.List;
/**
* Single Static Assignment Form Phi Statement.
* Selects appropriate value of a variable based on the actual control flow.
* <br>
* <i> X<sub>i</sub> := phi(X<sub>j</sub>, X<sub>k</sub>, ...) </i>
*/
public class StatementPhi implements StatementLValue {
/** The versioned variable being assigned a value by the statement. */
private VariableRef lValue;
/** The previous version of the rValue from predecessor control blocks. */
private List<PreviousSymbol> previousVersions;
public StatementPhi(VariableRef lValue) {
this.lValue = lValue;
this.previousVersions = new ArrayList<>();
}
@JsonCreator
StatementPhi(
@JsonProperty("lValue") VariableRef lValue,
@JsonProperty("previousVersions") List<PreviousSymbol> previousVersions) {
this.lValue = lValue;
this.previousVersions = previousVersions;
}
public PreviousSymbol getPreviousVersion(int i) {
return previousVersions.get(i);
}
/**
* 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.
*/
public static class PreviousSymbol {
private LabelRef block;
private RValue rValue;
@JsonCreator
public PreviousSymbol(
@JsonProperty("block") LabelRef block,
@JsonProperty("rValue") RValue rValue) {
this.block = block;
this.rValue = rValue;
}
public LabelRef getBlock() {
return block;
}
public RValue getrValue() {
return rValue;
}
public void setrValue(RValue RValue) {
this.rValue = RValue;
}
public void setBlock(LabelRef block) {
this.block = block;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PreviousSymbol that = (PreviousSymbol) o;
if (!block.equals(that.block)) return false;
return rValue.equals(that.rValue);
}
@Override
public int hashCode() {
int result = block.hashCode();
result = 31 * result + rValue.hashCode();
return result;
}
}
public VariableRef getlValue() {
return lValue;
}
@Override
public void setlValue(LValue lValue) {
if(!(lValue instanceof VariableRef)) {
throw new RuntimeException("Error modifying phi-statement lValue "+this.lValue+". Attempt to set to non-versioned variable "+lValue);
}
this.lValue = (VariableRef) lValue;
}
public void addPreviousVersion(LabelRef block, RValue rValue) {
previousVersions.add(new PreviousSymbol(block, rValue));
}
public List<PreviousSymbol> getPreviousVersions() {
return previousVersions;
}
@Override
public String toString() {
return getAsString();
}
@Override
public String getAsTypedString(ProgramScope scope) {
StringBuilder out = new StringBuilder();
out.append(lValue.getAsTypedString(scope) + "" + "phi(");
for (PreviousSymbol previousSymbol : previousVersions) {
out.append(" "+previousSymbol.getBlock().getFullName()+"/"+previousSymbol.getrValue().getAsTypedString(scope));
}
out.append(" )");
return out.toString();
}
@Override
public String getAsString() {
StringBuilder out = new StringBuilder();
out.append(lValue + "" + "phi(");
for (PreviousSymbol previousSymbol : previousVersions) {
out.append(" "+previousSymbol.getBlock().getFullName()+"/"+previousSymbol.getrValue());
}
out.append(" )");
return out.toString();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StatementPhi that = (StatementPhi) o;
if (!lValue.equals(that.lValue)) return false;
return previousVersions.equals(that.previousVersions);
}
@Override
public int hashCode() {
int result = lValue.hashCode();
result = 31 * result + previousVersions.hashCode();
return result;
}
}

View File

@ -0,0 +1,313 @@
package dk.camelot64.kickc.icl;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.*;
/**
* The Phi Block initializing the necessary SSA-variables of a predecessor.
* The phi predecessor initializes a number of variables with different values depending on which predecessor control flow enters from.
*/
public class StatementPhiBlock implements Statement {
/**
* Maps each phi-varible of the predecessor to a map from a predecessor predecessor to the rvalue of the variable.
*/
private List<PhiVariable> phiVariables;
@JsonCreator
public StatementPhiBlock(
@JsonProperty("phiVariables") List<PhiVariable> phiVariables) {
this.phiVariables = phiVariables;
}
public StatementPhiBlock() {
this.phiVariables = new ArrayList<>();
}
/**
* Get the ordered predecessor blocks where control can enter the predecessor.
*
* @return the predecessor blocks
*/
//public List<LabelRef> getPredecessors() {
// return predecessors;
//}
/**
* Get the variables defined by the phi predecessor.
*
* @return The variables defined
*/
@JsonIgnore
public List<VariableRef> getVariables() {
ArrayList<VariableRef> vars = new ArrayList<>();
for (PhiVariable phiVariable : phiVariables) {
vars.add(phiVariable.getVariable());
}
return vars;
}
public PhiVariable getPhiVariable(VariableRef variable) {
for (PhiVariable phiVariable : phiVariables) {
if (phiVariable.getVariable().equals(variable)) {
return phiVariable;
}
}
return null;
}
public RValue getrValue(LabelRef predecessor, VariableRef variable) {
return getPhiVariable(variable).getrValue(predecessor);
}
public PhiRValue getPhirValue(LabelRef predecessor, VariableRef variable) {
return getPhiVariable(variable).getPhirValue(predecessor);
}
@Override
public String getAsTypedString(ProgramScope scope) {
StringBuilder s = new StringBuilder();
List<PhiVariable> variables = new ArrayList<>(phiVariables);
Collections.reverse(variables);
for (PhiVariable phiVariable : variables) {
s.append(phiVariable.getVariable().getAsTypedString(scope));
s.append(" ← phi(");
for (PhiRValue phiRValue : phiVariable.getValues()) {
s.append(" ");
s.append(phiRValue.getPredecessor().getAsString());
s.append("/");
RValue rValue = phiRValue.getrValue();
s.append(rValue==null?"null":rValue.getAsTypedString(scope));
}
s.append(" )\n ");
}
if(s.length()>0) {
return s.toString().substring(0, s.length() - 3);
} else {
return s.toString();
}
}
@Override
public String getAsString() {
StringBuilder s = new StringBuilder();
List<PhiVariable> variables = new ArrayList<>(phiVariables);
Collections.reverse(variables);
for (PhiVariable phiVariable : variables) {
s.append(phiVariable.getVariable().getAsString());
s.append(" ← phi(");
for (PhiRValue phiRValue : phiVariable.getValues()) {
s.append(" ");
s.append(phiRValue.getPredecessor().getAsString());
s.append("/");
RValue rValue = phiRValue.getrValue();
s.append(rValue==null?"null":rValue.getAsString());
}
s.append(" )\n ");
}
if(s.length()>0) {
return s.toString().substring(0, s.length() - 3);
} else {
return s.toString();
}
}
public PhiVariable addPhiVariable(VariableRef variable) {
PhiVariable phiVariable = new PhiVariable(variable);
this.phiVariables.add(phiVariable);
return phiVariable;
}
public List<PhiVariable> getPhiVariables() {
return phiVariables;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StatementPhiBlock phiBlock = (StatementPhiBlock) o;
return phiVariables != null ? phiVariables.equals(phiBlock.phiVariables) : phiBlock.phiVariables == null;
}
@Override
public int hashCode() {
return phiVariables != null ? phiVariables.hashCode() : 0;
}
/**
* A variable being defined as part of a phi predecessor.
*/
public static class PhiVariable {
/**
* The variable being defined.
*/
private VariableRef variable;
/**
* The Rvalues assigned to the variable when entering from different blocks.
*/
private List<PhiRValue> values;
public PhiVariable(VariableRef variable) {
this.variable = variable;
this.values = new ArrayList<>();
}
@JsonCreator
public PhiVariable(
@JsonProperty("variable") VariableRef variable,
@JsonProperty("values") List<PhiRValue> values) {
this.variable = variable;
this.values = values;
}
public PhiVariable() {
}
public VariableRef getVariable() {
return variable;
}
public void setVariable(VariableRef variable) {
this.variable = variable;
}
public void setValues(List<PhiRValue> values) {
this.values = values;
}
public List<PhiRValue> getValues() {
return values;
}
public RValue getrValue(LabelRef predecessor) {
for (PhiRValue phiRValue : values) {
if (phiRValue.getPredecessor().equals(predecessor)) {
return phiRValue.getrValue();
}
}
return null;
}
/**
* Get the phi rvalue of the phi variable for a specific predecessor block.
* Creates the phi-rValue if it does not already exist.
*
* @param predecessor The predecessor block
* @return The rValue assigned to the phi variable when entering from the passed block.
*/
public PhiRValue getPhirValue(LabelRef predecessor) {
for (PhiRValue phiRValue : values) {
if (phiRValue.getPredecessor().equals(predecessor)) {
return phiRValue;
}
}
// Not found - create and return
PhiRValue phirValue = new PhiRValue(predecessor);
this.values.add(phirValue);
return phirValue;
}
public void setrValue(LabelRef predecessor, RValue rValue) {
getPhirValue(predecessor).setrValue(rValue);
}
@JsonIgnore
public boolean isEmpty() {
return this.values.isEmpty();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PhiVariable that = (PhiVariable) o;
if (!variable.equals(that.variable)) return false;
return values.equals(that.values);
}
@Override
public int hashCode() {
int result = variable.hashCode();
result = 31 * result + values.hashCode();
return result;
}
}
/**
* The value assigned to a phi variable when entering the predecessor from a specific predecessor block.
*/
public static class PhiRValue {
/**
* The predecessor predecessor
*/
private LabelRef predecessor;
/**
* The value to assign to the phi-variable when entering from the predecessor block
*/
private RValue rValue;
public PhiRValue(LabelRef predecessor) {
this.predecessor = predecessor;
}
@JsonCreator
public PhiRValue(
@JsonProperty("predecessor") LabelRef predecessor,
@JsonProperty("rValue") RValue rValue) {
this.predecessor = predecessor;
this.rValue = rValue;
}
public LabelRef getPredecessor() {
return predecessor;
}
public RValue getrValue() {
return rValue;
}
public void setrValue(RValue rValue) {
this.rValue = rValue;
}
public void setPredecessor(LabelRef predecessor) {
this.predecessor = predecessor;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PhiRValue phiRValue = (PhiRValue) o;
if (!predecessor.equals(phiRValue.predecessor)) return false;
return rValue != null ? rValue.equals(phiRValue.rValue) : phiRValue.rValue == null;
}
@Override
public int hashCode() {
int result = predecessor.hashCode();
result = 31 * result + (rValue != null ? rValue.hashCode() : 0);
return result;
}
}
}

View File

@ -30,6 +30,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
do {
log.append("Completing Phi functions...");
done = completePhiFunctions();
//log.append(this.controlFlowGraph.getAsTypedString(symbols));
} while (!done);
}
@ -124,7 +125,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
}
// Add new Phi functions to block
for (VariableUnversioned symbol : blockNewPhis.keySet()) {
block.addPhiStatement(blockNewPhis.get(symbol));
block.getPhiBlock().addPhiVariable(blockNewPhis.get(symbol).getRef());
}
}
}
@ -174,34 +175,37 @@ public class Pass1GenerateSingleStaticAssignmentForm {
Map<LabelRef, Map<VariableUnversioned, VariableVersion>> symbolMap = buildSymbolMap();
for (ControlFlowBlock block : this.controlFlowGraph.getAllBlocks()) {
for (Statement statement : block.getStatements()) {
if (statement instanceof StatementPhi) {
StatementPhi phi = (StatementPhi) statement;
if (phi.getPreviousVersions().isEmpty()) {
VariableRef phiLValVarRef = phi.getlValue();
VariableVersion versioned = (VariableVersion) symbols.getVariable(phiLValVarRef);
VariableUnversioned unversioned = versioned.getVersionOf();
for (ControlFlowBlock predecessor : controlFlowGraph.getPredecessors(block)) {
LabelRef predecessorLabel = predecessor.getLabel();
Map<VariableUnversioned, VariableVersion> predecessorMap = symbolMap.get(predecessorLabel);
VariableVersion previousSymbol = null;
if (predecessorMap != null) {
previousSymbol = predecessorMap.get(unversioned);
}
if (previousSymbol == null) {
// No previous symbol found in predecessor block. Look in new phi functions.
Map<VariableUnversioned, VariableVersion> predecessorNewPhis = newPhis.get(predecessorLabel);
if (predecessorNewPhis == null) {
predecessorNewPhis = new LinkedHashMap<>();
newPhis.put(predecessorLabel, predecessorNewPhis);
if (statement instanceof StatementPhiBlock) {
StatementPhiBlock phiBlock = (StatementPhiBlock) statement;
for (StatementPhiBlock.PhiVariable phiVariable : phiBlock.getPhiVariables()) {
if(phiVariable.isEmpty()) {
VariableRef phiLValVarRef = phiVariable.getVariable();
VariableVersion versioned = (VariableVersion) symbols.getVariable(phiLValVarRef);
VariableUnversioned unversioned = versioned.getVersionOf();
for (ControlFlowBlock predecessor : controlFlowGraph.getPredecessors(block)) {
LabelRef predecessorLabel = predecessor.getLabel();
Map<VariableUnversioned, VariableVersion> predecessorMap = symbolMap.get(predecessorLabel);
VariableVersion previousSymbol = null;
if (predecessorMap != null) {
previousSymbol = predecessorMap.get(unversioned);
}
previousSymbol = predecessorNewPhis.get(unversioned);
if (previousSymbol == null) {
// No previous symbol found in predecessor block. Add a new phi function to the predecessor.
previousSymbol = unversioned.createVersion();
predecessorNewPhis.put(unversioned, previousSymbol);
// No previous symbol found in predecessor block. Look in new phi functions.
Map<VariableUnversioned, VariableVersion> predecessorNewPhis = newPhis.get(predecessorLabel);
if (predecessorNewPhis == null) {
predecessorNewPhis = new LinkedHashMap<>();
newPhis.put(predecessorLabel, predecessorNewPhis);
}
previousSymbol = predecessorNewPhis.get(unversioned);
if (previousSymbol == null) {
// No previous symbol found in predecessor block. Add a new phi function to the predecessor.
previousSymbol = unversioned.createVersion();
predecessorNewPhis.put(unversioned, previousSymbol);
}
}
phiVariable.setrValue(predecessorLabel, previousSymbol.getRef());
}
phi.addPreviousVersion(predecessorLabel, previousSymbol.getRef());
}
}
}
@ -212,7 +216,8 @@ public class Pass1GenerateSingleStaticAssignmentForm {
Map<VariableUnversioned, VariableVersion> blockNewPhis = newPhis.get(block.getLabel());
if (blockNewPhis != null) {
for (VariableUnversioned symbol : blockNewPhis.keySet()) {
block.addPhiStatement(blockNewPhis.get(symbol));
StatementPhiBlock phiBlock = block.getPhiBlock();
phiBlock.addPhiVariable(blockNewPhis.get(symbol).getRef());
}
}
}
@ -229,23 +234,32 @@ public class Pass1GenerateSingleStaticAssignmentForm {
for (Statement statement : block.getStatements()) {
if (statement instanceof StatementLValue) {
StatementLValue assignment = (StatementLValue) statement;
LValue lValue = assignment.getlValue();
if(lValue instanceof VariableRef) {
Variable lValueVar = symbols.getVariable((VariableRef) lValue);
if (lValueVar instanceof VariableVersion) {
VariableVersion versioned = (VariableVersion) lValueVar;
LabelRef label = block.getLabel();
VariableUnversioned unversioned = versioned.getVersionOf();
Map<VariableUnversioned, VariableVersion> blockMap = symbolMap.get(label);
if (blockMap == null) {
blockMap = new LinkedHashMap<>();
symbolMap.put(label, blockMap);
}
blockMap.put(unversioned, versioned);
} }
addSymbolToMap(symbolMap, block, assignment.getlValue());
} else if(statement instanceof StatementPhiBlock) {
StatementPhiBlock phiBlock = (StatementPhiBlock) statement;
for (StatementPhiBlock.PhiVariable phiVariable : phiBlock.getPhiVariables()) {
addSymbolToMap(symbolMap, block, phiVariable.getVariable());
}
}
}
}
return symbolMap;
}
private void addSymbolToMap(Map<LabelRef, Map<VariableUnversioned, VariableVersion>> symbolMap, ControlFlowBlock block, LValue lValue) {
if(lValue instanceof VariableRef) {
Variable lValueVar = symbols.getVariable((VariableRef) lValue);
if (lValueVar instanceof VariableVersion) {
VariableVersion versioned = (VariableVersion) lValueVar;
LabelRef label = block.getLabel();
VariableUnversioned unversioned = versioned.getVersionOf();
Map<VariableUnversioned, VariableVersion> blockMap = symbolMap.get(label);
if (blockMap == null) {
blockMap = new LinkedHashMap<>();
symbolMap.put(label, blockMap);
}
blockMap.put(unversioned, versioned);
}
}
}
}

View File

@ -2,6 +2,7 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.icl.*;
import javafx.scene.input.InputMethodTextRun;
import java.util.*;
@ -54,14 +55,21 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
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();
} else if (statement instanceof StatementPhiBlock) {
StatementPhiBlock phiBlock = (StatementPhiBlock) statement;
Iterator<StatementPhiBlock.PhiVariable> variableIterator = phiBlock.getPhiVariables().iterator();
while (variableIterator.hasNext()) {
StatementPhiBlock.PhiVariable phiVariable = variableIterator.next();
AliasSet aliasSet = aliases.findAliasSet(phiVariable.getVariable());
if (aliasSet != null) {
if (phiVariable.getValues().size() == 1 && aliasSet.contains(phiVariable.getValues().get(0).getrValue())) {
variableIterator.remove();
}
}
}
if(phiBlock.getPhiVariables().size()==0) {
iterator.remove();
}
}
}
}
@ -222,32 +230,28 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
// Remove all candidates that are used after assignment in phi blocks
private void cleanupCandidates(Aliases candidates) {
for (final AliasSet aliasSet : candidates.aliases) {
final Boolean[] lMatch = {false};
ControlFlowGraphBaseVisitor<Void> candidateEliminator = new ControlFlowGraphBaseVisitor<Void>() {
@Override
public Void visitBlock(ControlFlowBlock block) {
lMatch[0] = false;
return super.visitBlock(block);
}
@Override
public Void visitPhi(StatementPhi phi) {
if(lMatch[0]) {
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
RValue phiRValue = previousSymbol.getrValue();
if (aliasSet.contains(phiRValue)) {
log.append("Alias candidate removed " + phiRValue.getAsTypedString(getSymbols()));
aliasSet.remove(phiRValue);
break;
for (ControlFlowBlock block : getGraph().getAllBlocks()) {
if(block.hasPhiBlock()) {
StatementPhiBlock phi = block.getPhiBlock();
boolean lMatch = false;
for (StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
if(lMatch) {
for (StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
RValue rValue = phiRValue.getrValue();
if (aliasSet.contains(rValue)) {
log.append("Alias candidate removed " + rValue.getAsTypedString(getSymbols()));
aliasSet.remove(rValue);
break;
}
}
} else {
if (aliasSet.contains(phiVariable.getVariable())) {
lMatch = true;
}
}
}
if (aliasSet.contains(phi.getlValue())) {
lMatch[0] = true;
}
return null;
}
};
candidateEliminator.visitGraph(getGraph());
}
}
}
@ -273,13 +277,15 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
}
@Override
public Void visitPhi(StatementPhi phi) {
if (phi.getPreviousVersions().size() == 1) {
StatementPhi.PreviousSymbol previousSymbol = phi.getPreviousVersions().get(0);
if (previousSymbol.getrValue() instanceof VariableRef) {
VariableRef variable = phi.getlValue();
VariableRef alias = (VariableRef) previousSymbol.getrValue();
aliases.add(variable, alias);
public Void visitPhiBlock(StatementPhiBlock phi) {
for (StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
if(phiVariable.getValues().size()==1) {
StatementPhiBlock.PhiRValue phiRValue = phiVariable.getValues().get(0);
if (phiRValue.getrValue() instanceof VariableRef) {
VariableRef variable = phiVariable.getVariable();
VariableRef alias = (VariableRef) phiRValue.getrValue();
aliases.add(variable, alias);
}
}
}
return null;

View File

@ -60,11 +60,13 @@ public class Pass2AssertBlocks extends Pass2SsaAssertion {
}
@Override
public Void visitPhi(StatementPhi phi) {
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
assertBlock(previousSymbol.getBlock());
public Void visitPhiBlock(StatementPhiBlock phi) {
for (StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
for (StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
assertBlock(phiRValue.getPredecessor());
}
}
return super.visitPhi(phi);
return super.visitPhiBlock(phi);
}
@Override

View File

@ -153,12 +153,14 @@ public class Pass2AssertSymbols extends Pass2SsaAssertion {
}
@Override
public Void visitPhi(StatementPhi phi) {
addSymbol(phi.getlValue());
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
addSymbol(previousSymbol.getrValue());
public Void visitPhiBlock(StatementPhiBlock phi) {
for (StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
addSymbol(phiVariable.getVariable());
for (StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
addSymbol(phiRValue.getrValue());
}
}
return super.visitPhi(phi);
return super.visitPhiBlock(phi);
}
}
}

View File

@ -68,17 +68,21 @@ public class Pass2ConstantPropagation extends Pass2SsaOptimization {
}
@Override
public Void visitPhi(StatementPhi phi) {
if (phi.getPreviousVersions().size() == 1) {
StatementPhi.PreviousSymbol previousSymbol = phi.getPreviousVersions().get(0);
if (previousSymbol.getrValue() instanceof Constant) {
VariableRef variable = phi.getlValue();
Constant constant = (Constant) previousSymbol.getrValue();
constants.put(variable, constant);
public Void visitPhiBlock(StatementPhiBlock phi) {
for (StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
if(phiVariable.getValues().size()==1) {
StatementPhiBlock.PhiRValue phiRValue = phiVariable.getValues().get(0);
if (phiRValue.getrValue() instanceof Constant) {
VariableRef variable = phiVariable.getVariable();
Constant constant = (Constant) phiRValue.getrValue();
constants.put(variable, constant);
}
}
}
return null;
}
};
visitor.visitGraph(getGraph());
return constants;

View File

@ -42,20 +42,22 @@ public class Pass2CullEmptyBlocks extends Pass2SsaOptimization {
// In all phi functions of a successor blocks make a copy of the phi assignment for each predecessor
ControlFlowGraphBaseVisitor<Void> phiFixVisitor = new ControlFlowGraphBaseVisitor<Void>() {
@Override
public Void visitPhi(StatementPhi phi) {
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
if(previousSymbol.getBlock().equals(removeBlock.getLabel())) {
// Found a phi function referencing the remove block - add copies for each predecessor
RValue previousRValue = previousSymbol.getrValue();
for (ControlFlowBlock predecessor : predecessors) {
if(previousSymbol!=null) {
previousSymbol.setBlock(predecessor.getLabel());
previousSymbol = null;
} else {
phi.addPreviousVersion(predecessor.getLabel(), previousRValue);
public Void visitPhiBlock(StatementPhiBlock phi) {
for (StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
for (StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
if(phiRValue.getPredecessor().equals(removeBlock.getLabel())) {
// Found a phi function referencing the remove block - add copies for each predecessor
RValue previousRValue = phiRValue.getrValue();
for (ControlFlowBlock predecessor : predecessors) {
if(phiRValue!=null) {
phiRValue.setPredecessor(predecessor.getLabel());
phiRValue = null;
} else {
phiVariable.setrValue(predecessor.getLabel(), previousRValue);
}
}
break;
}
break;
}
}
return null;

View File

@ -36,27 +36,31 @@ public class Pass2RedundantPhiElimination extends Pass2SsaOptimization {
private Map<VariableRef, RValue> findRedundantPhis() {
final Map<VariableRef, RValue> aliases = new LinkedHashMap<>();
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
@Override
public Void visitPhi(StatementPhi phi) {
boolean found = true;
RValue phiRValue = null;
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
if(phiRValue==null) {
phiRValue = previousSymbol.getrValue();
} else {
if(!phiRValue.equals(previousSymbol.getrValue())) {
found = false;
break;
public Void visitPhiBlock(StatementPhiBlock phi) {
for (StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
boolean found = true;
RValue rValue = null;
for (StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
if(rValue==null) {
rValue = phiRValue.getrValue();
} else {
if(!rValue.equals(phiRValue.getrValue())) {
found = false;
break;
}
}
}
}
if(found) {
VariableRef variable = phi.getlValue();
if(phiRValue==null) {phiRValue = VOID;}
aliases.put(variable, phiRValue);
if(found) {
VariableRef variable = phiVariable.getVariable();
if(rValue==null) {rValue = VOID;}
aliases.put(variable, rValue);
}
}
return null;
}
};
visitor.visitGraph(getGraph());
return aliases;

View File

@ -20,13 +20,16 @@ public class Pass2SelfPhiElimination extends Pass2SsaOptimization {
final Boolean[] optimized = {Boolean.FALSE};
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
@Override
public Void visitPhi(StatementPhi phi) {
for (Iterator<StatementPhi.PreviousSymbol> iterator = phi.getPreviousVersions().iterator(); iterator.hasNext(); ) {
StatementPhi.PreviousSymbol previousSymbol = iterator.next();
if (previousSymbol.getrValue().equals(phi.getlValue())) {
iterator.remove();
optimized[0] = Boolean.TRUE;
log.append("Self Phi Eliminated "+phi.getlValue().getAsTypedString(getSymbols()));
public Void visitPhiBlock(StatementPhiBlock phi) {
for (StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
Iterator<StatementPhiBlock.PhiRValue> iterator = phiVariable.getValues().iterator();
while (iterator.hasNext()) {
StatementPhiBlock.PhiRValue phiRValue = iterator.next();
if (phiRValue.getrValue().equals(phiVariable.getVariable())) {
iterator.remove();
optimized[0] = Boolean.TRUE;
log.append("Self Phi Eliminated "+phiVariable.getVariable().getAsTypedString(getSymbols()));
}
}
}
return null;

View File

@ -145,26 +145,31 @@ public abstract class Pass2SsaOptimization {
}
@Override
public Void visitPhi(StatementPhi phi) {
if (getAlias(aliases, phi.getlValue()) != null) {
RValue alias = getAlias(aliases, phi.getlValue());
if (alias instanceof LValue) {
phi.setlValue((VariableRef) alias);
public Void visitPhiBlock(StatementPhiBlock phi) {
for (StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
if (getAlias(aliases, phiVariable.getVariable()) != null) {
RValue alias = getAlias(aliases, phiVariable.getVariable());
if (alias instanceof LValue) {
phiVariable.setVariable((VariableRef) alias);
}
}
}
for (Iterator<StatementPhi.PreviousSymbol> iterator = phi.getPreviousVersions().iterator(); iterator.hasNext(); ) {
StatementPhi.PreviousSymbol previousSymbol = iterator.next();
if (getAlias(aliases, previousSymbol.getrValue()) != null) {
RValue alias = getAlias(aliases, previousSymbol.getrValue());
if (VOID.equals(alias)) {
iterator.remove();
} else {
previousSymbol.setrValue(alias);
List<StatementPhiBlock.PhiRValue> phirValues = phiVariable.getValues();
Iterator<StatementPhiBlock.PhiRValue> it = phirValues.iterator();
while (it.hasNext()) {
StatementPhiBlock.PhiRValue phirValue = it.next();
if (getAlias(aliases, phirValue.getrValue()) != null) {
RValue alias = getAlias(aliases, phirValue.getrValue());
if (VOID.equals(alias)) {
it.remove();
} else {
phirValue.setrValue(alias);
}
}
}
}
return null;
}
};
visitor.visitGraph(graph);
}
@ -184,16 +189,6 @@ public abstract class Pass2SsaOptimization {
return alias;
}
/**
* Replace all usages of a label in statements with another label.
*
* @param replacements Variables that have alias values.
*/
public void replaceLabels(final Map<LabelRef, LabelRef> replacements) {
ControlFlowGraphBaseVisitor<Void> visitor = getLabelReplaceVisitor(replacements);
visitor.visitGraph(graph);
}
/**
* Replace all usages of a label in statements with another label.
*
@ -208,33 +203,34 @@ public abstract class Pass2SsaOptimization {
private ControlFlowGraphBaseVisitor<Void> getLabelReplaceVisitor(final Map<LabelRef, LabelRef> replacements) {
return new ControlFlowGraphBaseVisitor<Void>() {
@Override
public Void visitConditionalJump(StatementConditionalJump conditionalJump) {
if (getReplacement(replacements, conditionalJump.getDestination()) != null) {
conditionalJump.setDestination(getReplacement(replacements, conditionalJump.getDestination()));
}
return null;
@Override
public Void visitConditionalJump(StatementConditionalJump conditionalJump) {
if (getReplacement(replacements, conditionalJump.getDestination()) != null) {
conditionalJump.setDestination(getReplacement(replacements, conditionalJump.getDestination()));
}
return null;
}
@Override
public Void visitJump(StatementJump jump) {
if (getReplacement(replacements, jump.getDestination()) != null) {
jump.setDestination(getReplacement(replacements, jump.getDestination()));
}
return null;
@Override
public Void visitJump(StatementJump jump) {
if (getReplacement(replacements, jump.getDestination()) != null) {
jump.setDestination(getReplacement(replacements, jump.getDestination()));
}
return null;
}
@Override
public Void visitPhi(StatementPhi phi) {
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
LabelRef replacement = getReplacement(replacements, previousSymbol.getBlock());
if (replacement != null) {
previousSymbol.setBlock(replacement);
@Override
public Void visitPhiBlock(StatementPhiBlock phi) {
for (StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
for (StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
if (getReplacement(replacements, phiRValue.getPredecessor()) != null) {
phiRValue.setPredecessor(getReplacement(replacements, phiRValue.getPredecessor()));
}
}
return null;
}
};
return null;
}
};
}
/**
@ -267,9 +263,16 @@ public abstract class Pass2SsaOptimization {
if (variables.contains(assignment.getlValue())) {
iterator.remove();
}
} else if (statement instanceof StatementPhi) {
StatementPhi phi = (StatementPhi) statement;
if (variables.contains(phi.getlValue())) {
} else if (statement instanceof StatementPhiBlock) {
StatementPhiBlock phiBlock = (StatementPhiBlock) statement;
Iterator<StatementPhiBlock.PhiVariable> variableIterator = phiBlock.getPhiVariables().iterator();
while (variableIterator.hasNext()) {
StatementPhiBlock.PhiVariable phiVariable = variableIterator.next();
if(variables.contains(phiVariable.getVariable())) {
variableIterator.remove();
}
}
if(phiBlock.getPhiVariables().size()==0) {
iterator.remove();
}
}
@ -326,9 +329,11 @@ public abstract class Pass2SsaOptimization {
}
@Override
public Void visitPhi(StatementPhi phi) {
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
addUsage(previousSymbol.getrValue(), phi);
public Void visitPhiBlock(StatementPhiBlock phi) {
for (StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
for (StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
addUsage(phiRValue.getrValue(), phi);
}
}
return null;
}
@ -393,12 +398,15 @@ public abstract class Pass2SsaOptimization {
}
@Override
public Object visitPhi(StatementPhi phi) {
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
addUsage(previousSymbol.getrValue());
public Void visitPhiBlock(StatementPhiBlock phi) {
for (StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
for (StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
addUsage(phiRValue.getrValue());
}
}
return null;
}
};
usageVisitor.visitGraph(getGraph());
return usages;

View File

@ -31,7 +31,7 @@ public class Pass3CodeGeneration {
// Generate exit
ControlFlowBlock defaultSuccessor = graph.getDefaultSuccessor(block);
if (defaultSuccessor != null) {
if (defaultSuccessor.hasPhiStatements()) {
if (defaultSuccessor.hasPhiBlock()) {
genBlockPhiTransition(asm, block, defaultSuccessor);
}
asm.addInstruction("JMP", AsmAddressingMode.ABS, defaultSuccessor.getLabel().getFullName().replace('@', 'B').replace(':','_'));
@ -44,7 +44,7 @@ public class Pass3CodeGeneration {
Iterator<Statement> statementsIt = block.getStatements().iterator();
while (statementsIt.hasNext()) {
Statement statement = statementsIt.next();
if (!(statement instanceof StatementPhi)) {
if (!(statement instanceof StatementPhiBlock)) {
if (statement instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) statement;
LValue lValue = assignment.getlValue();
@ -58,7 +58,7 @@ public class Pass3CodeGeneration {
StatementAssignment assignmentAlu = assignment;
statement = statementsIt.next();
if (!(statement instanceof StatementAssignment)) {
throw new RuntimeException("Error! ALU statement must be followed immidiately by assignment using the ALU. " + statement);
throw new RuntimeException("Error! ALU statement must be followed immediately by assignment using the ALU. " + statement);
}
assignment = (StatementAssignment) statement;
AsmFragment asmFragment = new AsmFragment(assignment, assignmentAlu, symbols);
@ -79,7 +79,7 @@ public class Pass3CodeGeneration {
} else if (statement instanceof StatementCall) {
StatementCall call = (StatementCall) statement;
ControlFlowBlock callSuccessor = graph.getCallSuccessor(block);
if (callSuccessor != null && callSuccessor.hasPhiStatements()) {
if (callSuccessor != null && callSuccessor.hasPhiBlock()) {
genBlockPhiTransition(asm, block, callSuccessor);
}
asm.addInstruction("jsr", AsmAddressingMode.ABS, call.getProcedure().getFullName());
@ -93,7 +93,7 @@ public class Pass3CodeGeneration {
}
private void genBlockEntryPoints(AsmProgram asm, ControlFlowBlock block) {
if (block.hasPhiStatements()) {
if (block.hasPhiBlock()) {
List<ControlFlowBlock> predecessors = new ArrayList<>(graph.getPredecessors(block));
Collections.sort(predecessors, new Comparator<ControlFlowBlock>() {
@Override
@ -111,24 +111,24 @@ public class Pass3CodeGeneration {
}
private void genBlockPhiTransition(AsmProgram asm, ControlFlowBlock fromBlock, ControlFlowBlock toBlock) {
asm.addLabel((toBlock.getLabel().getFullName() + "_from_" + fromBlock.getLabel().getLocalName()).replace('@', 'B').replace(':','_'));
for (Statement statement : toBlock.getStatements()) {
if (!(statement instanceof StatementPhi)) {
// No more phi statements to handle
break;
}
StatementPhi phi = (StatementPhi) statement;
List<StatementPhi.PreviousSymbol> previousVersions = new ArrayList<>(phi.getPreviousVersions());
Collections.sort(previousVersions, new Comparator<StatementPhi.PreviousSymbol>() {
@Override
public int compare(StatementPhi.PreviousSymbol o1, StatementPhi.PreviousSymbol o2) {
return o1.getBlock().getFullName().compareTo(o2.getBlock().getFullName());
}
});
for (StatementPhi.PreviousSymbol previousSymbol : previousVersions) {
if (previousSymbol.getBlock().equals(fromBlock.getLabel())) {
genAsmMove(asm, phi.getlValue(), previousSymbol.getrValue());
break;
asm.addLabel((toBlock.getLabel().getFullName() + "_from_" + fromBlock.getLabel().getLocalName()).replace('@', 'B').replace(':', '_'));
if (toBlock.hasPhiBlock()) {
StatementPhiBlock phiBlock = toBlock.getPhiBlock();
List<StatementPhiBlock.PhiVariable> phiVariables = new ArrayList<>(phiBlock.getPhiVariables());
Collections.reverse(phiVariables);
for (StatementPhiBlock.PhiVariable phiVariable : phiVariables) {
List<StatementPhiBlock.PhiRValue> phiRValues = phiVariable.getValues();
Collections.sort(phiRValues, new Comparator<StatementPhiBlock.PhiRValue>() {
@Override
public int compare(StatementPhiBlock.PhiRValue o1, StatementPhiBlock.PhiRValue o2) {
return o1.getPredecessor().getFullName().compareTo(o2.getPredecessor().getFullName());
}
});
for (StatementPhiBlock.PhiRValue phiRValue : phiRValues) {
if (phiRValue.getPredecessor().equals(fromBlock.getLabel())) {
genAsmMove(asm, phiVariable.getVariable(), phiRValue.getrValue());
break;
}
}
}
}

View File

@ -39,6 +39,16 @@ public class TestCompilationOutput extends TestCase {
tester.testFile("bresenham");
}
public void testMinus() throws IOException, URISyntaxException {
TestCompilationOutput tester = new TestCompilationOutput();
tester.testFile("minus");
}
public void testLoopMin() throws IOException, URISyntaxException {
TestCompilationOutput tester = new TestCompilationOutput();
tester.testFile("loopmin");
}
public void testSumMin() throws IOException, URISyntaxException {
TestCompilationOutput tester = new TestCompilationOutput();
tester.testFile("summin");

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,8 @@
byte i=10;
byte s=0;
do {
if(i>5) {
s=s+i;
}
i--;
} while (i>0)

View File

@ -14,13 +14,13 @@ B1_from_BBEGIN:
B1_from_B3:
lda 18
sta 14
lda 15
lda 17
sta 13
lda 2
sta 12
lda 16
lda 15
sta 10
lda 16+1
lda 15+1
sta 10+1
B1:
ldy #0
@ -47,12 +47,12 @@ B1:
B3_from_B1:
lda 14
sta 18
lda 3
sta 16
lda 3+1
sta 16+1
lda 5
sta 17
lda 3
sta 15
lda 3+1
sta 15+1
B3:
lda 2
cmp #40
@ -77,10 +77,10 @@ B2:
B3_from_B2:
lda 6
sta 18
lda 7
sta 16
lda 7+1
sta 16+1
lda 9
sta 17
lda 7
sta 15
lda 7+1
sta 15+1
jmp B3

View File

@ -17,9 +17,9 @@
(byte) e#2 ← (byte) e#1 - (byte) 39
to:@3
@3: from @1 @2
(byte) y#5 ← phi( @2/(byte) y#1 @1/(byte) y#2 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @1/(byte*) cursor#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @1/(byte) e#1 )
(byte) y#5 ← phi( @1/(byte) y#2 @2/(byte) y#1 )
(byte) e#5 ← phi( @1/(byte) e#1 @2/(byte) e#2 )
(byte*) cursor#5 ← phi( @1/(byte*) cursor#1 @2/(byte*) cursor#2 )
if((byte) x#1<(byte) 40) goto @1
to:@END
@END: from @3

View File

@ -249,8 +249,8 @@ CONTROL FLOW GRAPH SSA
@2: from @1 @5
(byte) yd#3 ← phi( @1/(byte) yd#1 @5/(byte) yd#5 )
(byte) STAR#3 ← phi( @1/(byte) STAR#1 @5/(byte) STAR#5 )
(byte) x1#2 ← phi( @1/(byte) x1#4 @5/(byte) x1#5 )
(byte) x#4 ← phi( @1/(byte) x#1 @5/(byte) x#6 )
(byte) x1#2 ← phi( @1/(byte) x1#4 @5/(byte) x1#5 )
(byte) xd#2 ← phi( @1/(byte) xd#1 @5/(byte) xd#4 )
(byte) e#4 ← phi( @1/(byte) e#1 @5/(byte) e#6 )
(byte*) cursor#4 ← phi( @1/(byte*) cursor#1 @5/(byte*) cursor#6 )
@ -269,16 +269,16 @@ CONTROL FLOW GRAPH SSA
(byte) e#7 ← phi( @1/(byte) e#1 )
(byte*) cursor#7 ← phi( @1/(byte*) cursor#1 )
(byte) STAR#4 ← phi( @1/(byte) STAR#1 )
(byte) x1#3 ← phi( @1/(byte) x1#4 )
(byte) x#5 ← phi( @1/(byte) x#1 )
(byte) x1#3 ← phi( @1/(byte) x1#4 )
to:@3
@3: from @2 @4
(byte) y#5 ← phi( @2/(byte) y#1 @4/(byte) y#6 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @4/(byte) STAR#4 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @4/(byte*) cursor#7 )
(byte) e#5 ← phi( @2/(byte) e#2 @4/(byte) e#7 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @4/(byte) yd#4 )
(byte) xd#3 ← phi( @2/(byte) xd#2 @4/(byte) xd#5 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @4/(byte) yd#4 )
(byte) e#5 ← phi( @2/(byte) e#2 @4/(byte) e#7 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @4/(byte*) cursor#7 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @4/(byte) STAR#4 )
(byte) x#3 ← phi( @2/(byte) x#4 @4/(byte) x#5 )
(byte) x1#1 ← phi( @2/(byte) x1#2 @4/(byte) x1#3 )
(byte~) $13 ← (byte) x1#1 + (byte) 1
@ -286,14 +286,14 @@ CONTROL FLOW GRAPH SSA
if((boolean~) $14) goto @1
to:@6
@5: from
(byte) STAR#5 ← phi( )
(byte) yd#5 ← phi( )
(byte) STAR#5 ← phi( )
(byte) x#6 ← phi( )
(byte) x1#5 ← phi( )
(byte) y#4 ← phi( )
(byte*) cursor#6 ← phi( )
(byte) e#6 ← phi( )
(byte) xd#4 ← phi( )
(byte) e#6 ← phi( )
(byte*) cursor#6 ← phi( )
(byte) y#4 ← phi( )
to:@2
@6: from @3
to:@END
@ -342,8 +342,8 @@ CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN
@2: from @1 @5
(byte) yd#3 ← phi( @1/(byte) yd#1 @5/(byte) yd#5 )
(byte) STAR#3 ← phi( @1/(byte) STAR#1 @5/(byte) STAR#5 )
(byte) x1#2 ← phi( @1/(byte) x1#4 @5/(byte) x1#5 )
(byte) x#4 ← phi( @1/(byte) x#1 @5/(byte) x#6 )
(byte) x1#2 ← phi( @1/(byte) x1#4 @5/(byte) x1#5 )
(byte) xd#2 ← phi( @1/(byte) xd#1 @5/(byte) xd#4 )
(byte) e#4 ← phi( @1/(byte) e#1 @5/(byte) e#6 )
(byte*) cursor#4 ← phi( @1/(byte*) cursor#1 @5/(byte*) cursor#6 )
@ -362,16 +362,16 @@ CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN
(byte) e#7 ← phi( @1/(byte) e#1 )
(byte*) cursor#7 ← phi( @1/(byte*) cursor#1 )
(byte) STAR#4 ← phi( @1/(byte) STAR#1 )
(byte) x1#3 ← phi( @1/(byte) x1#4 )
(byte) x#5 ← phi( @1/(byte) x#1 )
(byte) x1#3 ← phi( @1/(byte) x1#4 )
to:@3
@3: from @2 @4
(byte) y#5 ← phi( @2/(byte) y#1 @4/(byte) y#6 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @4/(byte) STAR#4 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @4/(byte*) cursor#7 )
(byte) e#5 ← phi( @2/(byte) e#2 @4/(byte) e#7 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @4/(byte) yd#4 )
(byte) xd#3 ← phi( @2/(byte) xd#2 @4/(byte) xd#5 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @4/(byte) yd#4 )
(byte) e#5 ← phi( @2/(byte) e#2 @4/(byte) e#7 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @4/(byte*) cursor#7 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @4/(byte) STAR#4 )
(byte) x#3 ← phi( @2/(byte) x#4 @4/(byte) x#5 )
(byte) x1#1 ← phi( @2/(byte) x1#2 @4/(byte) x1#3 )
(byte~) $13 ← (byte) x1#1 + (byte) 1
@ -379,14 +379,14 @@ CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN
if((boolean~) $14) goto @1
to:@6
@5: from
(byte) STAR#5 ← phi( )
(byte) yd#5 ← phi( )
(byte) STAR#5 ← phi( )
(byte) x#6 ← phi( )
(byte) x1#5 ← phi( )
(byte) y#4 ← phi( )
(byte*) cursor#6 ← phi( )
(byte) e#6 ← phi( )
(byte) xd#4 ← phi( )
(byte) e#6 ← phi( )
(byte*) cursor#6 ← phi( )
(byte) y#4 ← phi( )
to:@2
@6: from @3
to:@END
@ -437,8 +437,8 @@ CONTROL FLOW GRAPH
@2: from @1 @5
(byte) yd#3 ← phi( @1/(byte) yd#1 @5/(byte) yd#5 )
(byte) STAR#3 ← phi( @1/(byte) STAR#1 @5/(byte) STAR#5 )
(byte) x1#2 ← phi( @1/(byte) x1#4 @5/(byte) x1#5 )
(byte) x#4 ← phi( @1/(byte) x#1 @5/(byte) x#6 )
(byte) x1#2 ← phi( @1/(byte) x1#4 @5/(byte) x1#5 )
(byte) xd#2 ← phi( @1/(byte) xd#1 @5/(byte) xd#4 )
(byte) e#4 ← phi( @1/(byte) e#1 @5/(byte) e#6 )
(byte*) cursor#4 ← phi( @1/(byte*) cursor#1 @5/(byte*) cursor#6 )
@ -457,16 +457,16 @@ CONTROL FLOW GRAPH
(byte) e#7 ← phi( @1/(byte) e#1 )
(byte*) cursor#7 ← phi( @1/(byte*) cursor#1 )
(byte) STAR#4 ← phi( @1/(byte) STAR#1 )
(byte) x1#3 ← phi( @1/(byte) x1#4 )
(byte) x#5 ← phi( @1/(byte) x#1 )
(byte) x1#3 ← phi( @1/(byte) x1#4 )
to:@3
@3: from @2 @4
(byte) y#5 ← phi( @2/(byte) y#1 @4/(byte) y#6 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @4/(byte) STAR#4 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @4/(byte*) cursor#7 )
(byte) e#5 ← phi( @2/(byte) e#2 @4/(byte) e#7 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @4/(byte) yd#4 )
(byte) xd#3 ← phi( @2/(byte) xd#2 @4/(byte) xd#5 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @4/(byte) yd#4 )
(byte) e#5 ← phi( @2/(byte) e#2 @4/(byte) e#7 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @4/(byte*) cursor#7 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @4/(byte) STAR#4 )
(byte) x#3 ← phi( @2/(byte) x#4 @4/(byte) x#5 )
(byte) x1#1 ← phi( @2/(byte) x1#2 @4/(byte) x1#3 )
(byte~) $13 ← (byte) x1#1 + (byte) 1
@ -474,14 +474,14 @@ CONTROL FLOW GRAPH
if((boolean~) $14) goto @1
to:@END
@5: from
(byte) STAR#5 ← phi( )
(byte) yd#5 ← phi( )
(byte) STAR#5 ← phi( )
(byte) x#6 ← phi( )
(byte) x1#5 ← phi( )
(byte) y#4 ← phi( )
(byte*) cursor#6 ← phi( )
(byte) e#6 ← phi( )
(byte) xd#4 ← phi( )
(byte) e#6 ← phi( )
(byte*) cursor#6 ← phi( )
(byte) y#4 ← phi( )
to:@2
@END: from @3
@ -529,8 +529,8 @@ CONTROL FLOW GRAPH
@2: from @1 @5
(byte) yd#3 ← phi( @1/(byte) yd#1 @5/(byte) yd#5 )
(byte) STAR#3 ← phi( @1/(byte) STAR#1 @5/(byte) STAR#5 )
(byte) x1#2 ← phi( @1/(byte) x1#4 @5/(byte) x1#5 )
(byte) x#4 ← phi( @1/(byte) x#1 @5/(byte) x#6 )
(byte) x1#2 ← phi( @1/(byte) x1#4 @5/(byte) x1#5 )
(byte) xd#2 ← phi( @1/(byte) xd#1 @5/(byte) xd#4 )
(byte) e#4 ← phi( @1/(byte) e#1 @5/(byte) e#6 )
(byte*) cursor#4 ← phi( @1/(byte*) cursor#1 @5/(byte*) cursor#6 )
@ -549,16 +549,16 @@ CONTROL FLOW GRAPH
(byte) e#7 ← phi( @1/(byte) e#1 )
(byte*) cursor#7 ← phi( @1/(byte*) cursor#1 )
(byte) STAR#4 ← phi( @1/(byte) STAR#1 )
(byte) x1#3 ← phi( @1/(byte) x1#4 )
(byte) x#5 ← phi( @1/(byte) x#1 )
(byte) x1#3 ← phi( @1/(byte) x1#4 )
to:@3
@3: from @2 @4
(byte) y#5 ← phi( @2/(byte) y#1 @4/(byte) y#6 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @4/(byte) STAR#4 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @4/(byte*) cursor#7 )
(byte) e#5 ← phi( @2/(byte) e#2 @4/(byte) e#7 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @4/(byte) yd#4 )
(byte) xd#3 ← phi( @2/(byte) xd#2 @4/(byte) xd#5 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @4/(byte) yd#4 )
(byte) e#5 ← phi( @2/(byte) e#2 @4/(byte) e#7 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @4/(byte*) cursor#7 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @4/(byte) STAR#4 )
(byte) x#3 ← phi( @2/(byte) x#4 @4/(byte) x#5 )
(byte) x1#1 ← phi( @2/(byte) x1#2 @4/(byte) x1#3 )
(byte~) $13 ← (byte) x1#1 + (byte) 1
@ -566,14 +566,14 @@ CONTROL FLOW GRAPH
if((boolean~) $14) goto @1
to:@END
@5: from
(byte) STAR#5 ← phi( )
(byte) yd#5 ← phi( )
(byte) STAR#5 ← phi( )
(byte) x#6 ← phi( )
(byte) x1#5 ← phi( )
(byte) y#4 ← phi( )
(byte*) cursor#6 ← phi( )
(byte) e#6 ← phi( )
(byte) xd#4 ← phi( )
(byte) e#6 ← phi( )
(byte*) cursor#6 ← phi( )
(byte) y#4 ← phi( )
to:@2
@END: from @3
@ -588,11 +588,11 @@ Alias (byte) e#1 = (byte~) $8 (byte) e#7
Alias (byte) y#1 = (byte~) $10
Alias (byte*) cursor#2 = (byte*~) $11
Alias (byte) e#2 = (byte~) $12
Alias (byte) y#3 = (byte) y#6
Alias (byte) xd#1 = (byte) xd#5
Alias (byte) yd#1 = (byte) yd#4
Alias (byte) STAR#1 = (byte) STAR#4
Alias (byte) x1#3 = (byte) x1#4
Alias (byte) STAR#1 = (byte) STAR#4
Alias (byte) yd#1 = (byte) yd#4
Alias (byte) xd#1 = (byte) xd#5
Alias (byte) y#3 = (byte) y#6
Succesful SSA optimization Pass2AliasElimination
CONTROL FLOW GRAPH
@BEGIN: from
@ -624,8 +624,8 @@ CONTROL FLOW GRAPH
@2: from @1 @5
(byte) yd#3 ← phi( @1/(byte) yd#1 @5/(byte) yd#5 )
(byte) STAR#3 ← phi( @1/(byte) STAR#1 @5/(byte) STAR#5 )
(byte) x1#2 ← phi( @1/(byte) x1#3 @5/(byte) x1#5 )
(byte) x#4 ← phi( @1/(byte) x#1 @5/(byte) x#6 )
(byte) x1#2 ← phi( @1/(byte) x1#3 @5/(byte) x1#5 )
(byte) xd#2 ← phi( @1/(byte) xd#1 @5/(byte) xd#4 )
(byte) e#4 ← phi( @1/(byte) e#1 @5/(byte) e#6 )
(byte*) cursor#4 ← phi( @1/(byte*) cursor#1 @5/(byte*) cursor#6 )
@ -638,11 +638,11 @@ CONTROL FLOW GRAPH
to:@3
@3: from @2 @4
(byte) y#5 ← phi( @2/(byte) y#1 @4/(byte) y#3 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @4/(byte) STAR#1 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @4/(byte*) cursor#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @4/(byte) e#1 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @4/(byte) yd#1 )
(byte) xd#3 ← phi( @2/(byte) xd#2 @4/(byte) xd#1 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @4/(byte) yd#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @4/(byte) e#1 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @4/(byte*) cursor#1 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @4/(byte) STAR#1 )
(byte) x#3 ← phi( @2/(byte) x#4 @4/(byte) x#1 )
(byte) x1#1 ← phi( @2/(byte) x1#2 @4/(byte) x1#3 )
(byte~) $13 ← (byte) x1#1 + (byte) 1
@ -650,25 +650,25 @@ CONTROL FLOW GRAPH
if((boolean~) $14) goto @1
to:@END
@5: from
(byte) STAR#5 ← phi( )
(byte) yd#5 ← phi( )
(byte) STAR#5 ← phi( )
(byte) x#6 ← phi( )
(byte) x1#5 ← phi( )
(byte) y#4 ← phi( )
(byte*) cursor#6 ← phi( )
(byte) e#6 ← phi( )
(byte) xd#4 ← phi( )
(byte) e#6 ← phi( )
(byte*) cursor#6 ← phi( )
(byte) y#4 ← phi( )
to:@2
@END: from @3
Redundant Phi (byte) STAR#5 VOID
Redundant Phi (byte) yd#5 VOID
Redundant Phi (byte) x#6 VOID
Redundant Phi (byte) x1#5 VOID
Redundant Phi (byte) y#4 VOID
Redundant Phi (byte*) cursor#6 VOID
Redundant Phi (byte) e#6 VOID
Redundant Phi (byte) xd#4 VOID
Redundant Phi (byte) x1#5 VOID
Redundant Phi (byte) x#6 VOID
Redundant Phi (byte) STAR#5 VOID
Redundant Phi (byte) yd#5 VOID
Succesful SSA optimization Pass2RedundantPhiElimination
CONTROL FLOW GRAPH
@BEGIN: from
@ -700,8 +700,8 @@ CONTROL FLOW GRAPH
@2: from @1 @5
(byte) yd#3 ← phi( @1/(byte) yd#1 )
(byte) STAR#3 ← phi( @1/(byte) STAR#1 )
(byte) x1#2 ← phi( @1/(byte) x1#3 )
(byte) x#4 ← phi( @1/(byte) x#1 )
(byte) x1#2 ← phi( @1/(byte) x1#3 )
(byte) xd#2 ← phi( @1/(byte) xd#1 )
(byte) e#4 ← phi( @1/(byte) e#1 )
(byte*) cursor#4 ← phi( @1/(byte*) cursor#1 )
@ -714,11 +714,11 @@ CONTROL FLOW GRAPH
to:@3
@3: from @2 @4
(byte) y#5 ← phi( @2/(byte) y#1 @4/(byte) y#3 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @4/(byte) STAR#1 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @4/(byte*) cursor#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @4/(byte) e#1 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @4/(byte) yd#1 )
(byte) xd#3 ← phi( @2/(byte) xd#2 @4/(byte) xd#1 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @4/(byte) yd#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @4/(byte) e#1 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @4/(byte*) cursor#1 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @4/(byte) STAR#1 )
(byte) x#3 ← phi( @2/(byte) x#4 @4/(byte) x#1 )
(byte) x1#1 ← phi( @2/(byte) x1#2 @4/(byte) x1#3 )
(byte~) $13 ← (byte) x1#1 + (byte) 1
@ -761,8 +761,8 @@ CONTROL FLOW GRAPH
@2: from @1 @5
(byte) yd#3 ← phi( @1/(byte) yd#1 )
(byte) STAR#3 ← phi( @1/(byte) STAR#1 )
(byte) x1#2 ← phi( @1/(byte) x1#3 )
(byte) x#4 ← phi( @1/(byte) x#1 )
(byte) x1#2 ← phi( @1/(byte) x1#3 )
(byte) xd#2 ← phi( @1/(byte) xd#1 )
(byte) e#4 ← phi( @1/(byte) e#1 )
(byte*) cursor#4 ← phi( @1/(byte*) cursor#1 )
@ -775,11 +775,11 @@ CONTROL FLOW GRAPH
to:@3
@3: from @2 @4
(byte) y#5 ← phi( @2/(byte) y#1 @4/(byte) y#3 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @4/(byte) STAR#1 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @4/(byte*) cursor#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @4/(byte) e#1 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @4/(byte) yd#1 )
(byte) xd#3 ← phi( @2/(byte) xd#2 @4/(byte) xd#1 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @4/(byte) yd#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @4/(byte) e#1 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @4/(byte*) cursor#1 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @4/(byte) STAR#1 )
(byte) x#3 ← phi( @2/(byte) x#4 @4/(byte) x#1 )
(byte) x1#1 ← phi( @2/(byte) x1#2 @4/(byte) x1#3 )
(byte~) $13 ← (byte) x1#1 + (byte) 1
@ -821,8 +821,8 @@ CONTROL FLOW GRAPH
@2: from @1
(byte) yd#3 ← phi( @1/(byte) yd#1 )
(byte) STAR#3 ← phi( @1/(byte) STAR#1 )
(byte) x1#2 ← phi( @1/(byte) x1#3 )
(byte) x#4 ← phi( @1/(byte) x#1 )
(byte) x1#2 ← phi( @1/(byte) x1#3 )
(byte) xd#2 ← phi( @1/(byte) xd#1 )
(byte) e#4 ← phi( @1/(byte) e#1 )
(byte*) cursor#4 ← phi( @1/(byte*) cursor#1 )
@ -833,11 +833,11 @@ CONTROL FLOW GRAPH
to:@3
@3: from @1 @2
(byte) y#5 ← phi( @2/(byte) y#1 @1/(byte) y#3 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @1/(byte) STAR#1 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @1/(byte*) cursor#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @1/(byte) e#1 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @1/(byte) yd#1 )
(byte) xd#3 ← phi( @2/(byte) xd#2 @1/(byte) xd#1 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @1/(byte) yd#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @1/(byte) e#1 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @1/(byte*) cursor#1 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @1/(byte) STAR#1 )
(byte) x#3 ← phi( @2/(byte) x#4 @1/(byte) x#1 )
(byte) x1#1 ← phi( @2/(byte) x1#2 @1/(byte) x1#3 )
(byte~) $13 ← (byte) x1#1 + (byte) 1
@ -875,8 +875,8 @@ CONTROL FLOW GRAPH
@2: from @1
(byte) yd#3 ← phi( @1/(byte) yd#1 )
(byte) STAR#3 ← phi( @1/(byte) STAR#1 )
(byte) x1#2 ← phi( @1/(byte) x1#3 )
(byte) x#4 ← phi( @1/(byte) x#1 )
(byte) x1#2 ← phi( @1/(byte) x1#3 )
(byte) xd#2 ← phi( @1/(byte) xd#1 )
(byte) e#4 ← phi( @1/(byte) e#1 )
(byte*) cursor#4 ← phi( @1/(byte*) cursor#1 )
@ -887,11 +887,11 @@ CONTROL FLOW GRAPH
to:@3
@3: from @1 @2
(byte) y#5 ← phi( @2/(byte) y#1 @1/(byte) y#3 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @1/(byte) STAR#1 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @1/(byte*) cursor#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @1/(byte) e#1 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @1/(byte) yd#1 )
(byte) xd#3 ← phi( @2/(byte) xd#2 @1/(byte) xd#1 )
(byte) yd#2 ← phi( @2/(byte) yd#3 @1/(byte) yd#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @1/(byte) e#1 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @1/(byte*) cursor#1 )
(byte) STAR#2 ← phi( @2/(byte) STAR#3 @1/(byte) STAR#1 )
(byte) x#3 ← phi( @2/(byte) x#4 @1/(byte) x#1 )
(byte) x1#1 ← phi( @2/(byte) x1#2 @1/(byte) x1#3 )
(byte~) $13 ← (byte) x1#1 + (byte) 1
@ -900,14 +900,14 @@ CONTROL FLOW GRAPH
@END: from @3
Multiple usages for variable. Not optimizing sub-constant (byte) x1#1
Alias (byte) yd#1 = (byte) yd#3
Alias (byte) STAR#1 = (byte) STAR#3
Alias (byte) y#2 = (byte) y#3
Alias (byte*) cursor#1 = (byte*) cursor#4
Alias (byte) e#1 = (byte) e#4
Alias (byte) xd#1 = (byte) xd#2
Alias (byte) x1#2 = (byte) x1#3
Alias (byte) x#1 = (byte) x#4
Alias (byte) xd#1 = (byte) xd#2
Alias (byte) e#1 = (byte) e#4
Alias (byte*) cursor#1 = (byte*) cursor#4
Alias (byte) y#2 = (byte) y#3
Alias (byte) STAR#1 = (byte) STAR#3
Alias (byte) yd#1 = (byte) yd#3
Succesful SSA optimization Pass2AliasElimination
CONTROL FLOW GRAPH
@BEGIN: from
@ -938,11 +938,11 @@ CONTROL FLOW GRAPH
to:@3
@3: from @1 @2
(byte) y#5 ← phi( @2/(byte) y#1 @1/(byte) y#2 )
(byte) STAR#2 ← phi( @2/(byte) STAR#1 @1/(byte) STAR#1 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @1/(byte*) cursor#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @1/(byte) e#1 )
(byte) yd#2 ← phi( @2/(byte) yd#1 @1/(byte) yd#1 )
(byte) xd#3 ← phi( @2/(byte) xd#1 @1/(byte) xd#1 )
(byte) yd#2 ← phi( @2/(byte) yd#1 @1/(byte) yd#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @1/(byte) e#1 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @1/(byte*) cursor#1 )
(byte) STAR#2 ← phi( @2/(byte) STAR#1 @1/(byte) STAR#1 )
(byte) x#3 ← phi( @2/(byte) x#1 @1/(byte) x#1 )
(byte) x1#1 ← phi( @2/(byte) x1#2 @1/(byte) x1#2 )
(byte~) $13 ← (byte) x1#1 + (byte) 1
@ -950,11 +950,11 @@ CONTROL FLOW GRAPH
to:@END
@END: from @3
Redundant Phi (byte) x1#1 (byte) x1#2
Redundant Phi (byte) x#3 (byte) x#1
Redundant Phi (byte) STAR#2 (byte) STAR#1
Redundant Phi (byte) yd#2 (byte) yd#1
Redundant Phi (byte) xd#3 (byte) xd#1
Redundant Phi (byte) x#3 (byte) x#1
Redundant Phi (byte) x1#1 (byte) x1#2
Succesful SSA optimization Pass2RedundantPhiElimination
CONTROL FLOW GRAPH
@BEGIN: from
@ -985,17 +985,17 @@ CONTROL FLOW GRAPH
to:@3
@3: from @1 @2
(byte) y#5 ← phi( @2/(byte) y#1 @1/(byte) y#2 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @1/(byte*) cursor#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @1/(byte) e#1 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @1/(byte*) cursor#1 )
(byte~) $13 ← (byte) x1#2 + (byte) 1
if((byte) x#1<(byte~) $13) goto @1
to:@END
@END: from @3
Self Phi Eliminated (byte) x1#2
Self Phi Eliminated (byte) xd#1
Self Phi Eliminated (byte) yd#1
Self Phi Eliminated (byte) STAR#1
Self Phi Eliminated (byte) yd#1
Self Phi Eliminated (byte) xd#1
Self Phi Eliminated (byte) x1#2
Succesful SSA optimization Pass2SelfPhiElimination
CONTROL FLOW GRAPH
@BEGIN: from
@ -1026,8 +1026,8 @@ CONTROL FLOW GRAPH
to:@3
@3: from @1 @2
(byte) y#5 ← phi( @2/(byte) y#1 @1/(byte) y#2 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @1/(byte*) cursor#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @1/(byte) e#1 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @1/(byte*) cursor#1 )
(byte~) $13 ← (byte) x1#2 + (byte) 1
if((byte) x#1<(byte~) $13) goto @1
to:@END
@ -1035,10 +1035,10 @@ CONTROL FLOW GRAPH
Constant (byte) e#0 (byte) 12
Constant (byte~) $3 (byte) 0
Constant (byte) x1#2 (byte) 39
Constant (byte) xd#1 (byte) 39
Constant (byte) yd#1 (byte) 24
Constant (byte) STAR#1 (byte) 81
Constant (byte) yd#1 (byte) 24
Constant (byte) xd#1 (byte) 39
Constant (byte) x1#2 (byte) 39
Succesful SSA optimization Pass2ConstantPropagation
CONTROL FLOW GRAPH
@BEGIN: from
@ -1063,8 +1063,8 @@ CONTROL FLOW GRAPH
to:@3
@3: from @1 @2
(byte) y#5 ← phi( @2/(byte) y#1 @1/(byte) y#2 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @1/(byte*) cursor#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @1/(byte) e#1 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @1/(byte*) cursor#1 )
(byte~) $13 ← (byte) 39 + (byte) 1
if((byte) x#1<(byte~) $13) goto @1
to:@END
@ -1097,8 +1097,8 @@ CONTROL FLOW GRAPH
to:@3
@3: from @1 @2
(byte) y#5 ← phi( @2/(byte) y#1 @1/(byte) y#2 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @1/(byte*) cursor#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @1/(byte) e#1 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @1/(byte*) cursor#1 )
if((byte) x#1<(byte) 40) goto @1
to:@END
@END: from @3
@ -1128,8 +1128,8 @@ CONTROL FLOW GRAPH
to:@3
@3: from @1 @2
(byte) y#5 ← phi( @2/(byte) y#1 @1/(byte) y#2 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @1/(byte*) cursor#1 )
(byte) e#5 ← phi( @2/(byte) e#2 @1/(byte) e#1 )
(byte*) cursor#5 ← phi( @2/(byte*) cursor#2 @1/(byte*) cursor#1 )
if((byte) x#1<(byte) 40) goto @1
to:@END
@END: from @3
@ -1161,15 +1161,15 @@ B1_from_B3:
lda 18
sta 14
// (byte) e#3 = (byte) e#5 // zpby1=zpby2
lda 15
lda 17
sta 13
// (byte) x#2 = (byte) x#1 // zpby1=zpby2
lda 2
sta 12
// (byte*) cursor#3 = (byte*) cursor#5 // zpptrby1=zpptrby2
lda 16
lda 15
sta 10
lda 16+1
lda 15+1
sta 10+1
jmp B1
B1:
@ -1203,14 +1203,14 @@ B3_from_B1:
// (byte) y#5 = (byte) y#2 // zpby1=zpby2
lda 14
sta 18
// (byte*) cursor#5 = (byte*) cursor#1 // zpptrby1=zpptrby2
lda 3
sta 16
lda 3+1
sta 16+1
// (byte) e#5 = (byte) e#1 // zpby1=zpby2
lda 5
sta 17
// (byte*) cursor#5 = (byte*) cursor#1 // zpptrby1=zpptrby2
lda 3
sta 15
lda 3+1
sta 15+1
jmp B3
B3:
// if((byte) x#1<(byte) 40) goto @1 // zpby1_lt_coby1_then_la1
@ -1242,14 +1242,14 @@ B3_from_B2:
// (byte) y#5 = (byte) y#1 // zpby1=zpby2
lda 6
sta 18
// (byte*) cursor#5 = (byte*) cursor#2 // zpptrby1=zpptrby2
lda 7
sta 16
lda 7+1
sta 16+1
// (byte) e#5 = (byte) e#2 // zpby1=zpby2
lda 9
sta 17
// (byte*) cursor#5 = (byte*) cursor#2 // zpptrby1=zpptrby2
lda 7
sta 15
lda 7+1
sta 15+1
jmp B3
Removing instruction jmp B1
@ -1279,15 +1279,15 @@ B1_from_B3:
lda 18
sta 14
// (byte) e#3 = (byte) e#5 // zpby1=zpby2
lda 15
lda 17
sta 13
// (byte) x#2 = (byte) x#1 // zpby1=zpby2
lda 2
sta 12
// (byte*) cursor#3 = (byte*) cursor#5 // zpptrby1=zpptrby2
lda 16
lda 15
sta 10
lda 16+1
lda 15+1
sta 10+1
B1:
// *((byte*) cursor#3) ← (byte) 81 // zpiby1=coby1
@ -1320,14 +1320,14 @@ B3_from_B1:
// (byte) y#5 = (byte) y#2 // zpby1=zpby2
lda 14
sta 18
// (byte*) cursor#5 = (byte*) cursor#1 // zpptrby1=zpptrby2
lda 3
sta 16
lda 3+1
sta 16+1
// (byte) e#5 = (byte) e#1 // zpby1=zpby2
lda 5
sta 17
// (byte*) cursor#5 = (byte*) cursor#1 // zpptrby1=zpptrby2
lda 3
sta 15
lda 3+1
sta 15+1
B3:
// if((byte) x#1<(byte) 40) goto @1 // zpby1_lt_coby1_then_la1
lda 2
@ -1357,14 +1357,14 @@ B3_from_B2:
// (byte) y#5 = (byte) y#1 // zpby1=zpby2
lda 6
sta 18
// (byte*) cursor#5 = (byte*) cursor#2 // zpptrby1=zpptrby2
lda 7
sta 16
lda 7+1
sta 16+1
// (byte) e#5 = (byte) e#2 // zpby1=zpby2
lda 9
sta 17
// (byte*) cursor#5 = (byte*) cursor#2 // zpptrby1=zpptrby2
lda 7
sta 15
lda 7+1
sta 15+1
jmp B3
FINAL SYMBOL TABLE
@ -1379,12 +1379,12 @@ FINAL SYMBOL TABLE
(byte*) cursor#1 zp ptr byte:3
(byte*) cursor#2 zp ptr byte:7
(byte*) cursor#3 zp ptr byte:10
(byte*) cursor#5 zp ptr byte:16
(byte*) cursor#5 zp ptr byte:15
(byte) e
(byte) e#1 zp byte:5
(byte) e#2 zp byte:9
(byte) e#3 zp byte:13
(byte) e#5 zp byte:15
(byte) e#5 zp byte:17
(byte) x
(byte) x#1 zp byte:2
(byte) x#2 zp byte:12
@ -1422,15 +1422,15 @@ B1_from_B3:
lda 18
sta 14
// (byte) e#3 = (byte) e#5 // zpby1=zpby2
lda 15
lda 17
sta 13
// (byte) x#2 = (byte) x#1 // zpby1=zpby2
lda 2
sta 12
// (byte*) cursor#3 = (byte*) cursor#5 // zpptrby1=zpptrby2
lda 16
lda 15
sta 10
lda 16+1
lda 15+1
sta 10+1
B1:
// *((byte*) cursor#3) ← (byte) 81 // zpiby1=coby1
@ -1463,14 +1463,14 @@ B3_from_B1:
// (byte) y#5 = (byte) y#2 // zpby1=zpby2
lda 14
sta 18
// (byte*) cursor#5 = (byte*) cursor#1 // zpptrby1=zpptrby2
lda 3
sta 16
lda 3+1
sta 16+1
// (byte) e#5 = (byte) e#1 // zpby1=zpby2
lda 5
sta 17
// (byte*) cursor#5 = (byte*) cursor#1 // zpptrby1=zpptrby2
lda 3
sta 15
lda 3+1
sta 15+1
B3:
// if((byte) x#1<(byte) 40) goto @1 // zpby1_lt_coby1_then_la1
lda 2
@ -1500,13 +1500,13 @@ B3_from_B2:
// (byte) y#5 = (byte) y#1 // zpby1=zpby2
lda 6
sta 18
// (byte*) cursor#5 = (byte*) cursor#2 // zpptrby1=zpptrby2
lda 7
sta 16
lda 7+1
sta 16+1
// (byte) e#5 = (byte) e#2 // zpby1=zpby2
lda 9
sta 17
// (byte*) cursor#5 = (byte*) cursor#2 // zpptrby1=zpptrby2
lda 7
sta 15
lda 7+1
sta 15+1
jmp B3

View File

@ -9,12 +9,12 @@
(byte*) cursor#1 zp ptr byte:3
(byte*) cursor#2 zp ptr byte:7
(byte*) cursor#3 zp ptr byte:10
(byte*) cursor#5 zp ptr byte:16
(byte*) cursor#5 zp ptr byte:15
(byte) e
(byte) e#1 zp byte:5
(byte) e#2 zp byte:9
(byte) e#3 zp byte:13
(byte) e#5 zp byte:15
(byte) e#5 zp byte:17
(byte) x
(byte) x#1 zp byte:2
(byte) x#2 zp byte:12

View File

@ -34,11 +34,11 @@ plot:
plot__B1_from_plot:
lda #16
sta 100
ldx #0
lda #<1236
sta 101
lda #>1236
sta 101+1
ldx #0
plot__B1_from_B3:
plot__B1:
plot__B2_from_B1:
@ -68,8 +68,8 @@ flip:
flip__B1_from_flip:
lda #16
sta 104
ldx #0
ldy #15
ldx #0
flip__B1_from_B4:
flip__B1:
flip__B2_from_B1:

View File

@ -5,7 +5,7 @@ main: from @BEGIN
call prepare param-assignment
to:main::@2
main::@2: from main main::@11 main::@6
(byte) main::c#2 ← phi( main/(byte) 25 main::@6/(byte) main::c#1 main::@11/(byte) 25 )
(byte) main::c#2 ← phi( main/(byte) 25 main::@11/(byte) 25 main::@6/(byte) main::c#1 )
to:main::@3
main::@3: from main::@2 main::@3
(byte~) main::$1 ← * (word) 53266
@ -46,8 +46,8 @@ flip: from main::@7
to:flip::@1
flip::@1: from flip flip::@4
(byte) flip::r#2 ← phi( flip/(byte) 16 flip::@4/(byte) flip::r#1 )
(byte) flip::srcIdx#3 ← phi( flip/(byte) 0 flip::@4/(byte) flip::srcIdx#1 )
(byte) flip::dstIdx#5 ← phi( flip/(byte) 15 flip::@4/(byte) flip::dstIdx#2 )
(byte) flip::srcIdx#3 ← phi( flip/(byte) 0 flip::@4/(byte) flip::srcIdx#1 )
to:flip::@2
flip::@2: from flip::@1 flip::@2
(byte) flip::c#2 ← phi( flip::@1/(byte) 16 flip::@2/(byte) flip::c#1 )
@ -79,8 +79,8 @@ plot: from main::@10
to:plot::@1
plot::@1: from plot plot::@3
(byte) plot::y#2 ← phi( plot/(byte) 16 plot::@3/(byte) plot::y#1 )
(byte) plot::i#3 ← phi( plot/(byte) 0 plot::@3/(byte) plot::i#1 )
(byte*) plot::line#2 ← phi( plot/(word) 1236 plot::@3/(byte*) plot::line#1 )
(byte) plot::i#3 ← phi( plot/(byte) 0 plot::@3/(byte) plot::i#1 )
to:plot::@2
plot::@2: from plot::@1 plot::@2
(byte) plot::x#2 ← phi( plot::@1/(byte) 0 plot::@2/(byte) plot::x#1 )

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
BBEGIN:
B1_from_BBEGIN:
lda #0
sta 5
lda #10
sta 4
jmp B1
B1_from_B3:
lda 6
sta 5
lda 3
sta 4
B1:
lda 4
cmp #5
beq !+
bcs B2
!:
B3_from_B1:
lda 5
sta 6
B3:
lda 4
sta 3
dec 3
lda 3
bne B1_from_B3
BEND:
B2:
lda 5
clc
adc 4
sta 2
B3_from_B2:
lda 2
sta 6
jmp B3

View File

@ -0,0 +1,16 @@
@BEGIN: from
to:@1
@1: from @3 @BEGIN
(byte) s#2 ← phi( @3/(byte) s#5 @BEGIN/(byte) 0 )
(byte) i#2 ← phi( @3/(byte) i#1 @BEGIN/(byte) 10 )
if((byte) i#2>(byte) 5) goto @2
to:@3
@2: from @1
(byte) s#1 ← (byte) s#2 + (byte) i#2
to:@3
@3: from @1 @2
(byte) s#5 ← phi( @1/(byte) s#2 @2/(byte) s#1 )
(byte) i#1 ← -- (byte) i#2
if((byte) i#1>(byte) 0) goto @1
to:@END
@END: from @3

View File

@ -0,0 +1,558 @@
byte i=10;
byte s=0;
do {
if(i>5) {
s=s+i;
}
i--;
} while (i>0)
Adding pre/post-modifier (byte) i ← -- (byte) i
PROGRAM
(byte) i ← (byte) 10
(byte) s ← (byte) 0
@1:
(boolean~) $0 ← (byte) i > (byte) 5
if((boolean~) $0) goto @2
goto @3
@2:
(byte~) $1 ← (byte) s + (byte) i
(byte) s ← (byte~) $1
@3:
(byte) i ← -- (byte) i
(boolean~) $2 ← (byte) i > (byte) 0
if((boolean~) $2) goto @1
SYMBOLS
(boolean~) $0
(byte~) $1
(boolean~) $2
(label) @1
(label) @2
(label) @3
(byte) i
(byte) s
INITIAL CONTROL FLOW GRAPH
@BEGIN: from
(byte) i ← (byte) 10
(byte) s ← (byte) 0
to:@1
@1: from @3 @BEGIN
(boolean~) $0 ← (byte) i > (byte) 5
if((boolean~) $0) goto @2
to:@4
@2: from @1 @5
(byte~) $1 ← (byte) s + (byte) i
(byte) s ← (byte~) $1
to:@3
@4: from @1
to:@3
@3: from @2 @4
(byte) i ← -- (byte) i
(boolean~) $2 ← (byte) i > (byte) 0
if((boolean~) $2) goto @1
to:@6
@5: from
to:@2
@6: from @3
to:@END
@END: from @6
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@BEGIN: from
(byte) i ← (byte) 10
(byte) s ← (byte) 0
to:@1
@1: from @3 @BEGIN
(boolean~) $0 ← (byte) i > (byte) 5
if((boolean~) $0) goto @2
to:@4
@2: from @1 @5
(byte~) $1 ← (byte) s + (byte) i
(byte) s ← (byte~) $1
to:@3
@4: from @1
to:@3
@3: from @2 @4
(byte) i ← -- (byte) i
(boolean~) $2 ← (byte) i > (byte) 0
if((boolean~) $2) goto @1
to:@6
@5: from
to:@2
@6: from @3
to:@END
@END: from @6
Completing Phi functions...
Completing Phi functions...
Completing Phi functions...
Completing Phi functions...
CONTROL FLOW GRAPH SSA
@BEGIN: from
(byte) i#0 ← (byte) 10
(byte) s#0 ← (byte) 0
to:@1
@1: from @3 @BEGIN
(byte) s#3 ← phi( @3/(byte) s#5 @BEGIN/(byte) s#0 )
(byte) i#2 ← phi( @3/(byte) i#1 @BEGIN/(byte) i#0 )
(boolean~) $0 ← (byte) i#2 > (byte) 5
if((boolean~) $0) goto @2
to:@4
@2: from @1 @5
(byte) i#3 ← phi( @1/(byte) i#2 @5/(byte) i#5 )
(byte) s#2 ← phi( @1/(byte) s#3 @5/(byte) s#4 )
(byte~) $1 ← (byte) s#2 + (byte) i#3
(byte) s#1 ← (byte~) $1
to:@3
@4: from @1
(byte) s#6 ← phi( @1/(byte) s#3 )
(byte) i#6 ← phi( @1/(byte) i#2 )
to:@3
@3: from @2 @4
(byte) s#5 ← phi( @2/(byte) s#1 @4/(byte) s#6 )
(byte) i#4 ← phi( @2/(byte) i#3 @4/(byte) i#6 )
(byte) i#1 ← -- (byte) i#4
(boolean~) $2 ← (byte) i#1 > (byte) 0
if((boolean~) $2) goto @1
to:@6
@5: from
(byte) i#5 ← phi( )
(byte) s#4 ← phi( )
to:@2
@6: from @3
to:@END
@END: from @6
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN
@BEGIN: from
(byte) i#0 ← (byte) 10
(byte) s#0 ← (byte) 0
to:@1
@1: from @3 @BEGIN
(byte) s#3 ← phi( @3/(byte) s#5 @BEGIN/(byte) s#0 )
(byte) i#2 ← phi( @3/(byte) i#1 @BEGIN/(byte) i#0 )
(boolean~) $0 ← (byte) i#2 > (byte) 5
if((boolean~) $0) goto @2
to:@4
@2: from @1 @5
(byte) i#3 ← phi( @1/(byte) i#2 @5/(byte) i#5 )
(byte) s#2 ← phi( @1/(byte) s#3 @5/(byte) s#4 )
(byte~) $1 ← (byte) s#2 + (byte) i#3
(byte) s#1 ← (byte~) $1
to:@3
@4: from @1
(byte) s#6 ← phi( @1/(byte) s#3 )
(byte) i#6 ← phi( @1/(byte) i#2 )
to:@3
@3: from @2 @4
(byte) s#5 ← phi( @2/(byte) s#1 @4/(byte) s#6 )
(byte) i#4 ← phi( @2/(byte) i#3 @4/(byte) i#6 )
(byte) i#1 ← -- (byte) i#4
(boolean~) $2 ← (byte) i#1 > (byte) 0
if((boolean~) $2) goto @1
to:@6
@5: from
(byte) i#5 ← phi( )
(byte) s#4 ← phi( )
to:@2
@6: from @3
to:@END
@END: from @6
Culled Empty Block (label) @6
Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH
@BEGIN: from
(byte) i#0 ← (byte) 10
(byte) s#0 ← (byte) 0
to:@1
@1: from @3 @BEGIN
(byte) s#3 ← phi( @3/(byte) s#5 @BEGIN/(byte) s#0 )
(byte) i#2 ← phi( @3/(byte) i#1 @BEGIN/(byte) i#0 )
(boolean~) $0 ← (byte) i#2 > (byte) 5
if((boolean~) $0) goto @2
to:@4
@2: from @1 @5
(byte) i#3 ← phi( @1/(byte) i#2 @5/(byte) i#5 )
(byte) s#2 ← phi( @1/(byte) s#3 @5/(byte) s#4 )
(byte~) $1 ← (byte) s#2 + (byte) i#3
(byte) s#1 ← (byte~) $1
to:@3
@4: from @1
(byte) s#6 ← phi( @1/(byte) s#3 )
(byte) i#6 ← phi( @1/(byte) i#2 )
to:@3
@3: from @2 @4
(byte) s#5 ← phi( @2/(byte) s#1 @4/(byte) s#6 )
(byte) i#4 ← phi( @2/(byte) i#3 @4/(byte) i#6 )
(byte) i#1 ← -- (byte) i#4
(boolean~) $2 ← (byte) i#1 > (byte) 0
if((boolean~) $2) goto @1
to:@END
@5: from
(byte) i#5 ← phi( )
(byte) s#4 ← phi( )
to:@2
@END: from @3
Constant (byte) i#0 (byte) 10
Constant (byte) s#0 (byte) 0
Succesful SSA optimization Pass2ConstantPropagation
CONTROL FLOW GRAPH
@BEGIN: from
to:@1
@1: from @3 @BEGIN
(byte) s#3 ← phi( @3/(byte) s#5 @BEGIN/(byte) 0 )
(byte) i#2 ← phi( @3/(byte) i#1 @BEGIN/(byte) 10 )
(boolean~) $0 ← (byte) i#2 > (byte) 5
if((boolean~) $0) goto @2
to:@4
@2: from @1 @5
(byte) i#3 ← phi( @1/(byte) i#2 @5/(byte) i#5 )
(byte) s#2 ← phi( @1/(byte) s#3 @5/(byte) s#4 )
(byte~) $1 ← (byte) s#2 + (byte) i#3
(byte) s#1 ← (byte~) $1
to:@3
@4: from @1
(byte) s#6 ← phi( @1/(byte) s#3 )
(byte) i#6 ← phi( @1/(byte) i#2 )
to:@3
@3: from @2 @4
(byte) s#5 ← phi( @2/(byte) s#1 @4/(byte) s#6 )
(byte) i#4 ← phi( @2/(byte) i#3 @4/(byte) i#6 )
(byte) i#1 ← -- (byte) i#4
(boolean~) $2 ← (byte) i#1 > (byte) 0
if((boolean~) $2) goto @1
to:@END
@5: from
(byte) i#5 ← phi( )
(byte) s#4 ← phi( )
to:@2
@END: from @3
Alias (byte) s#1 = (byte~) $1
Alias (byte) i#2 = (byte) i#6
Alias (byte) s#3 = (byte) s#6
Succesful SSA optimization Pass2AliasElimination
CONTROL FLOW GRAPH
@BEGIN: from
to:@1
@1: from @3 @BEGIN
(byte) s#3 ← phi( @3/(byte) s#5 @BEGIN/(byte) 0 )
(byte) i#2 ← phi( @3/(byte) i#1 @BEGIN/(byte) 10 )
(boolean~) $0 ← (byte) i#2 > (byte) 5
if((boolean~) $0) goto @2
to:@4
@2: from @1 @5
(byte) i#3 ← phi( @1/(byte) i#2 @5/(byte) i#5 )
(byte) s#2 ← phi( @1/(byte) s#3 @5/(byte) s#4 )
(byte) s#1 ← (byte) s#2 + (byte) i#3
to:@3
@4: from @1
to:@3
@3: from @2 @4
(byte) s#5 ← phi( @2/(byte) s#1 @4/(byte) s#3 )
(byte) i#4 ← phi( @2/(byte) i#3 @4/(byte) i#2 )
(byte) i#1 ← -- (byte) i#4
(boolean~) $2 ← (byte) i#1 > (byte) 0
if((boolean~) $2) goto @1
to:@END
@5: from
(byte) i#5 ← phi( )
(byte) s#4 ← phi( )
to:@2
@END: from @3
Redundant Phi (byte) s#4 VOID
Redundant Phi (byte) i#5 VOID
Succesful SSA optimization Pass2RedundantPhiElimination
CONTROL FLOW GRAPH
@BEGIN: from
to:@1
@1: from @3 @BEGIN
(byte) s#3 ← phi( @3/(byte) s#5 @BEGIN/(byte) 0 )
(byte) i#2 ← phi( @3/(byte) i#1 @BEGIN/(byte) 10 )
(boolean~) $0 ← (byte) i#2 > (byte) 5
if((boolean~) $0) goto @2
to:@4
@2: from @1 @5
(byte) i#3 ← phi( @1/(byte) i#2 )
(byte) s#2 ← phi( @1/(byte) s#3 )
(byte) s#1 ← (byte) s#2 + (byte) i#3
to:@3
@4: from @1
to:@3
@3: from @2 @4
(byte) s#5 ← phi( @2/(byte) s#1 @4/(byte) s#3 )
(byte) i#4 ← phi( @2/(byte) i#3 @4/(byte) i#2 )
(byte) i#1 ← -- (byte) i#4
(boolean~) $2 ← (byte) i#1 > (byte) 0
if((boolean~) $2) goto @1
to:@END
@5: from
to:@2
@END: from @3
Simple Condition (boolean~) $0 if((byte) i#2>(byte) 5) goto @2
Simple Condition (boolean~) $2 if((byte) i#1>(byte) 0) goto @1
Succesful SSA optimization Pass2ConditionalJumpSimplification
CONTROL FLOW GRAPH
@BEGIN: from
to:@1
@1: from @3 @BEGIN
(byte) s#3 ← phi( @3/(byte) s#5 @BEGIN/(byte) 0 )
(byte) i#2 ← phi( @3/(byte) i#1 @BEGIN/(byte) 10 )
if((byte) i#2>(byte) 5) goto @2
to:@4
@2: from @1 @5
(byte) i#3 ← phi( @1/(byte) i#2 )
(byte) s#2 ← phi( @1/(byte) s#3 )
(byte) s#1 ← (byte) s#2 + (byte) i#3
to:@3
@4: from @1
to:@3
@3: from @2 @4
(byte) s#5 ← phi( @2/(byte) s#1 @4/(byte) s#3 )
(byte) i#4 ← phi( @2/(byte) i#3 @4/(byte) i#2 )
(byte) i#1 ← -- (byte) i#4
if((byte) i#1>(byte) 0) goto @1
to:@END
@5: from
to:@2
@END: from @3
Culled Empty Block (label) @4
Culled Empty Block (label) @5
Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH
@BEGIN: from
to:@1
@1: from @3 @BEGIN
(byte) s#3 ← phi( @3/(byte) s#5 @BEGIN/(byte) 0 )
(byte) i#2 ← phi( @3/(byte) i#1 @BEGIN/(byte) 10 )
if((byte) i#2>(byte) 5) goto @2
to:@3
@2: from @1
(byte) i#3 ← phi( @1/(byte) i#2 )
(byte) s#2 ← phi( @1/(byte) s#3 )
(byte) s#1 ← (byte) s#2 + (byte) i#3
to:@3
@3: from @1 @2
(byte) s#5 ← phi( @2/(byte) s#1 @1/(byte) s#3 )
(byte) i#4 ← phi( @2/(byte) i#3 @1/(byte) i#2 )
(byte) i#1 ← -- (byte) i#4
if((byte) i#1>(byte) 0) goto @1
to:@END
@END: from @3
Alias (byte) s#2 = (byte) s#3
Alias (byte) i#2 = (byte) i#3
Succesful SSA optimization Pass2AliasElimination
CONTROL FLOW GRAPH
@BEGIN: from
to:@1
@1: from @3 @BEGIN
(byte) s#2 ← phi( @3/(byte) s#5 @BEGIN/(byte) 0 )
(byte) i#2 ← phi( @3/(byte) i#1 @BEGIN/(byte) 10 )
if((byte) i#2>(byte) 5) goto @2
to:@3
@2: from @1
(byte) s#1 ← (byte) s#2 + (byte) i#2
to:@3
@3: from @1 @2
(byte) s#5 ← phi( @2/(byte) s#1 @1/(byte) s#2 )
(byte) i#4 ← phi( @2/(byte) i#2 @1/(byte) i#2 )
(byte) i#1 ← -- (byte) i#4
if((byte) i#1>(byte) 0) goto @1
to:@END
@END: from @3
Redundant Phi (byte) i#4 (byte) i#2
Succesful SSA optimization Pass2RedundantPhiElimination
CONTROL FLOW GRAPH
@BEGIN: from
to:@1
@1: from @3 @BEGIN
(byte) s#2 ← phi( @3/(byte) s#5 @BEGIN/(byte) 0 )
(byte) i#2 ← phi( @3/(byte) i#1 @BEGIN/(byte) 10 )
if((byte) i#2>(byte) 5) goto @2
to:@3
@2: from @1
(byte) s#1 ← (byte) s#2 + (byte) i#2
to:@3
@3: from @1 @2
(byte) s#5 ← phi( @2/(byte) s#1 @1/(byte) s#2 )
(byte) i#1 ← -- (byte) i#2
if((byte) i#1>(byte) 0) goto @1
to:@END
@END: from @3
INITIAL ASM
BBEGIN:
B1_from_BBEGIN:
// (byte) s#2 = (byte) 0 // zpby1=coby1
lda #0
sta 5
// (byte) i#2 = (byte) 10 // zpby1=coby1
lda #10
sta 4
jmp B1
B1_from_B3:
// (byte) s#2 = (byte) s#5 // zpby1=zpby2
lda 6
sta 5
// (byte) i#2 = (byte) i#1 // zpby1=zpby2
lda 3
sta 4
jmp B1
B1:
// if((byte) i#2>(byte) 5) goto @2 // zpby1_gt_coby1_then_la1
lda 4
cmp #5
beq !+
bcs B2
!:
B3_from_B1:
// (byte) s#5 = (byte) s#2 // zpby1=zpby2
lda 5
sta 6
jmp B3
B3:
// (byte) i#1 ← -- (byte) i#2 // zpby1=_dec_zpby2
lda 4
sta 3
dec 3
// if((byte) i#1>(byte) 0) goto @1 // zpby1_gt_0_then_la1
lda 3
bne B1_from_B3
jmp BEND
BEND:
B2:
// (byte) s#1 ← (byte) s#2 + (byte) i#2 // zpby1=zpby2_plus_zpby3
lda 5
clc
adc 4
sta 2
B3_from_B2:
// (byte) s#5 = (byte) s#1 // zpby1=zpby2
lda 2
sta 6
jmp B3
Removing instruction jmp B1
Removing instruction jmp B3
Removing instruction jmp BEND
Succesful ASM optimization Pass4NextJumpElimination
ASSEMBLER
BBEGIN:
B1_from_BBEGIN:
// (byte) s#2 = (byte) 0 // zpby1=coby1
lda #0
sta 5
// (byte) i#2 = (byte) 10 // zpby1=coby1
lda #10
sta 4
jmp B1
B1_from_B3:
// (byte) s#2 = (byte) s#5 // zpby1=zpby2
lda 6
sta 5
// (byte) i#2 = (byte) i#1 // zpby1=zpby2
lda 3
sta 4
B1:
// if((byte) i#2>(byte) 5) goto @2 // zpby1_gt_coby1_then_la1
lda 4
cmp #5
beq !+
bcs B2
!:
B3_from_B1:
// (byte) s#5 = (byte) s#2 // zpby1=zpby2
lda 5
sta 6
B3:
// (byte) i#1 ← -- (byte) i#2 // zpby1=_dec_zpby2
lda 4
sta 3
dec 3
// if((byte) i#1>(byte) 0) goto @1 // zpby1_gt_0_then_la1
lda 3
bne B1_from_B3
BEND:
B2:
// (byte) s#1 ← (byte) s#2 + (byte) i#2 // zpby1=zpby2_plus_zpby3
lda 5
clc
adc 4
sta 2
B3_from_B2:
// (byte) s#5 = (byte) s#1 // zpby1=zpby2
lda 2
sta 6
jmp B3
FINAL SYMBOL TABLE
(label) @1
(label) @2
(label) @3
(label) @BEGIN
(label) @END
(byte) i
(byte) i#1 zp byte:3
(byte) i#2 zp byte:4
(byte) s
(byte) s#1 zp byte:2
(byte) s#2 zp byte:5
(byte) s#5 zp byte:6
FINAL CODE
BBEGIN:
B1_from_BBEGIN:
// (byte) s#2 = (byte) 0 // zpby1=coby1
lda #0
sta 5
// (byte) i#2 = (byte) 10 // zpby1=coby1
lda #10
sta 4
jmp B1
B1_from_B3:
// (byte) s#2 = (byte) s#5 // zpby1=zpby2
lda 6
sta 5
// (byte) i#2 = (byte) i#1 // zpby1=zpby2
lda 3
sta 4
B1:
// if((byte) i#2>(byte) 5) goto @2 // zpby1_gt_coby1_then_la1
lda 4
cmp #5
beq !+
bcs B2
!:
B3_from_B1:
// (byte) s#5 = (byte) s#2 // zpby1=zpby2
lda 5
sta 6
B3:
// (byte) i#1 ← -- (byte) i#2 // zpby1=_dec_zpby2
lda 4
sta 3
dec 3
// if((byte) i#1>(byte) 0) goto @1 // zpby1_gt_0_then_la1
lda 3
bne B1_from_B3
BEND:
B2:
// (byte) s#1 ← (byte) s#2 + (byte) i#2 // zpby1=zpby2_plus_zpby3
lda 5
clc
adc 4
sta 2
B3_from_B2:
// (byte) s#5 = (byte) s#1 // zpby1=zpby2
lda 2
sta 6
jmp B3

View File

@ -0,0 +1,12 @@
(label) @1
(label) @2
(label) @3
(label) @BEGIN
(label) @END
(byte) i
(byte) i#1 zp byte:3
(byte) i#2 zp byte:4
(byte) s
(byte) s#1 zp byte:2
(byte) s#2 zp byte:5
(byte) s#5 zp byte:6

View File

@ -0,0 +1,28 @@
BBEGIN:
B1_from_BBEGIN:
lda #5
sta 5
jmp B1
B1_from_B1:
lda 4
sta 5
B1:
lda #2
clc
adc 5
sta 2
lda 2
clc
adc #2
sta 3
lda 3
ldy 5
sta 4352,y
lda 5
clc
adc #1
sta 4
lda 4
cmp #10
bcc B1_from_B1
BEND:

View File

@ -0,0 +1,11 @@
@BEGIN: from
to:@1
@1: from @1 @BEGIN
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 5 )
(byte~) $0 ← (byte) 2 + (byte) i#2
(byte~) $1 ← (byte~) $0 + (byte) 2
*((word) 4352 + (byte) i#2) ← (byte~) $1
(byte) i#1 ← (byte) i#2 + (byte) 1
if((byte) i#1<(byte) 10) goto @1
to:@END
@END: from @1

View File

@ -0,0 +1,344 @@
byte[16] p = $1100;
byte i = 5;
do {
p[i] = 2+i+2;
i = i+1;
} while(i<10)
PROGRAM
(byte[16]) p ← (word) 4352
(byte) i ← (byte) 5
@1:
(byte~) $0 ← (byte) 2 + (byte) i
(byte~) $1 ← (byte~) $0 + (byte) 2
*((byte[16]) p + (byte) i) ← (byte~) $1
(byte~) $2 ← (byte) i + (byte) 1
(byte) i ← (byte~) $2
(boolean~) $3 ← (byte) i < (byte) 10
if((boolean~) $3) goto @1
SYMBOLS
(byte~) $0
(byte~) $1
(byte~) $2
(boolean~) $3
(label) @1
(byte) i
(byte[16]) p
INITIAL CONTROL FLOW GRAPH
@BEGIN: from
(byte[16]) p ← (word) 4352
(byte) i ← (byte) 5
to:@1
@1: from @1 @BEGIN
(byte~) $0 ← (byte) 2 + (byte) i
(byte~) $1 ← (byte~) $0 + (byte) 2
*((byte[16]) p + (byte) i) ← (byte~) $1
(byte~) $2 ← (byte) i + (byte) 1
(byte) i ← (byte~) $2
(boolean~) $3 ← (byte) i < (byte) 10
if((boolean~) $3) goto @1
to:@2
@2: from @1
to:@END
@END: from @2
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@BEGIN: from
(byte[16]) p ← (word) 4352
(byte) i ← (byte) 5
to:@1
@1: from @1 @BEGIN
(byte~) $0 ← (byte) 2 + (byte) i
(byte~) $1 ← (byte~) $0 + (byte) 2
*((byte[16]) p + (byte) i) ← (byte~) $1
(byte~) $2 ← (byte) i + (byte) 1
(byte) i ← (byte~) $2
(boolean~) $3 ← (byte) i < (byte) 10
if((boolean~) $3) goto @1
to:@2
@2: from @1
to:@END
@END: from @2
Completing Phi functions...
CONTROL FLOW GRAPH SSA
@BEGIN: from
(byte[16]) p#0 ← (word) 4352
(byte) i#0 ← (byte) 5
to:@1
@1: from @1 @BEGIN
(byte[16]) p#1 ← phi( @1/(byte[16]) p#1 @BEGIN/(byte[16]) p#0 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) i#0 )
(byte~) $0 ← (byte) 2 + (byte) i#2
(byte~) $1 ← (byte~) $0 + (byte) 2
*((byte[16]) p#1 + (byte) i#2) ← (byte~) $1
(byte~) $2 ← (byte) i#2 + (byte) 1
(byte) i#1 ← (byte~) $2
(boolean~) $3 ← (byte) i#1 < (byte) 10
if((boolean~) $3) goto @1
to:@2
@2: from @1
to:@END
@END: from @2
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN
@BEGIN: from
(byte[16]) p#0 ← (word) 4352
(byte) i#0 ← (byte) 5
to:@1
@1: from @1 @BEGIN
(byte[16]) p#1 ← phi( @1/(byte[16]) p#1 @BEGIN/(byte[16]) p#0 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) i#0 )
(byte~) $0 ← (byte) 2 + (byte) i#2
(byte~) $1 ← (byte~) $0 + (byte) 2
*((byte[16]) p#1 + (byte) i#2) ← (byte~) $1
(byte~) $2 ← (byte) i#2 + (byte) 1
(byte) i#1 ← (byte~) $2
(boolean~) $3 ← (byte) i#1 < (byte) 10
if((boolean~) $3) goto @1
to:@2
@2: from @1
to:@END
@END: from @2
Culled Empty Block (label) @2
Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH
@BEGIN: from
(byte[16]) p#0 ← (word) 4352
(byte) i#0 ← (byte) 5
to:@1
@1: from @1 @BEGIN
(byte[16]) p#1 ← phi( @1/(byte[16]) p#1 @BEGIN/(byte[16]) p#0 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) i#0 )
(byte~) $0 ← (byte) 2 + (byte) i#2
(byte~) $1 ← (byte~) $0 + (byte) 2
*((byte[16]) p#1 + (byte) i#2) ← (byte~) $1
(byte~) $2 ← (byte) i#2 + (byte) 1
(byte) i#1 ← (byte~) $2
(boolean~) $3 ← (byte) i#1 < (byte) 10
if((boolean~) $3) goto @1
to:@END
@END: from @1
Constant (byte[16]) p#0 (word) 4352
Constant (byte) i#0 (byte) 5
Succesful SSA optimization Pass2ConstantPropagation
CONTROL FLOW GRAPH
@BEGIN: from
to:@1
@1: from @1 @BEGIN
(byte[16]) p#1 ← phi( @1/(byte[16]) p#1 @BEGIN/(word) 4352 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 5 )
(byte~) $0 ← (byte) 2 + (byte) i#2
(byte~) $1 ← (byte~) $0 + (byte) 2
*((byte[16]) p#1 + (byte) i#2) ← (byte~) $1
(byte~) $2 ← (byte) i#2 + (byte) 1
(byte) i#1 ← (byte~) $2
(boolean~) $3 ← (byte) i#1 < (byte) 10
if((boolean~) $3) goto @1
to:@END
@END: from @1
Multiple usages for variable. Not optimizing sub-constant (byte) i#2
Multiple usages for variable. Not optimizing sub-constant (byte) i#2
Alias (byte) i#1 = (byte~) $2
Succesful SSA optimization Pass2AliasElimination
CONTROL FLOW GRAPH
@BEGIN: from
to:@1
@1: from @1 @BEGIN
(byte[16]) p#1 ← phi( @1/(byte[16]) p#1 @BEGIN/(word) 4352 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 5 )
(byte~) $0 ← (byte) 2 + (byte) i#2
(byte~) $1 ← (byte~) $0 + (byte) 2
*((byte[16]) p#1 + (byte) i#2) ← (byte~) $1
(byte) i#1 ← (byte) i#2 + (byte) 1
(boolean~) $3 ← (byte) i#1 < (byte) 10
if((boolean~) $3) goto @1
to:@END
@END: from @1
Self Phi Eliminated (byte[16]) p#1
Succesful SSA optimization Pass2SelfPhiElimination
CONTROL FLOW GRAPH
@BEGIN: from
to:@1
@1: from @1 @BEGIN
(byte[16]) p#1 ← phi( @BEGIN/(word) 4352 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 5 )
(byte~) $0 ← (byte) 2 + (byte) i#2
(byte~) $1 ← (byte~) $0 + (byte) 2
*((byte[16]) p#1 + (byte) i#2) ← (byte~) $1
(byte) i#1 ← (byte) i#2 + (byte) 1
(boolean~) $3 ← (byte) i#1 < (byte) 10
if((boolean~) $3) goto @1
to:@END
@END: from @1
Simple Condition (boolean~) $3 if((byte) i#1<(byte) 10) goto @1
Succesful SSA optimization Pass2ConditionalJumpSimplification
CONTROL FLOW GRAPH
@BEGIN: from
to:@1
@1: from @1 @BEGIN
(byte[16]) p#1 ← phi( @BEGIN/(word) 4352 )
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 5 )
(byte~) $0 ← (byte) 2 + (byte) i#2
(byte~) $1 ← (byte~) $0 + (byte) 2
*((byte[16]) p#1 + (byte) i#2) ← (byte~) $1
(byte) i#1 ← (byte) i#2 + (byte) 1
if((byte) i#1<(byte) 10) goto @1
to:@END
@END: from @1
Constant (byte[16]) p#1 (word) 4352
Succesful SSA optimization Pass2ConstantPropagation
CONTROL FLOW GRAPH
@BEGIN: from
to:@1
@1: from @1 @BEGIN
(byte) i#2 ← phi( @1/(byte) i#1 @BEGIN/(byte) 5 )
(byte~) $0 ← (byte) 2 + (byte) i#2
(byte~) $1 ← (byte~) $0 + (byte) 2
*((word) 4352 + (byte) i#2) ← (byte~) $1
(byte) i#1 ← (byte) i#2 + (byte) 1
if((byte) i#1<(byte) 10) goto @1
to:@END
@END: from @1
Multiple usages for variable. Not optimizing sub-constant (byte) i#2
Multiple usages for variable. Not optimizing sub-constant (byte) i#2
Multiple usages for variable. Not optimizing sub-constant (byte) i#2
Multiple usages for variable. Not optimizing sub-constant (byte) i#2
Multiple usages for variable. Not optimizing sub-constant (byte) i#2
Multiple usages for variable. Not optimizing sub-constant (byte) i#2
INITIAL ASM
BBEGIN:
B1_from_BBEGIN:
// (byte) i#2 = (byte) 5 // zpby1=coby1
lda #5
sta 5
jmp B1
B1_from_B1:
// (byte) i#2 = (byte) i#1 // zpby1=zpby2
lda 4
sta 5
jmp B1
B1:
// (byte~) $0 ← (byte) 2 + (byte) i#2 // zpby1=coby1_plus_zpby2
lda #2
clc
adc 5
sta 2
// (byte~) $1 ← (byte~) $0 + (byte) 2 // zpby1=zpby2_plus_coby1
lda 2
clc
adc #2
sta 3
// *((word) 4352 + (byte) i#2) ← (byte~) $1 // ptr_cowo1_zpby1=zpby2
lda 3
ldy 5
sta 4352,y
// (byte) i#1 ← (byte) i#2 + (byte) 1 // zpby1=zpby2_plus_1
lda 5
clc
adc #1
sta 4
// if((byte) i#1<(byte) 10) goto @1 // zpby1_lt_coby1_then_la1
lda 4
cmp #10
bcc B1_from_B1
jmp BEND
BEND:
Removing instruction jmp B1
Removing instruction jmp BEND
Succesful ASM optimization Pass4NextJumpElimination
ASSEMBLER
BBEGIN:
B1_from_BBEGIN:
// (byte) i#2 = (byte) 5 // zpby1=coby1
lda #5
sta 5
jmp B1
B1_from_B1:
// (byte) i#2 = (byte) i#1 // zpby1=zpby2
lda 4
sta 5
B1:
// (byte~) $0 ← (byte) 2 + (byte) i#2 // zpby1=coby1_plus_zpby2
lda #2
clc
adc 5
sta 2
// (byte~) $1 ← (byte~) $0 + (byte) 2 // zpby1=zpby2_plus_coby1
lda 2
clc
adc #2
sta 3
// *((word) 4352 + (byte) i#2) ← (byte~) $1 // ptr_cowo1_zpby1=zpby2
lda 3
ldy 5
sta 4352,y
// (byte) i#1 ← (byte) i#2 + (byte) 1 // zpby1=zpby2_plus_1
lda 5
clc
adc #1
sta 4
// if((byte) i#1<(byte) 10) goto @1 // zpby1_lt_coby1_then_la1
lda 4
cmp #10
bcc B1_from_B1
BEND:
FINAL SYMBOL TABLE
(byte~) $0 zp byte:2
(byte~) $1 zp byte:3
(label) @1
(label) @BEGIN
(label) @END
(byte) i
(byte) i#1 zp byte:4
(byte) i#2 zp byte:5
(byte[16]) p
FINAL CODE
BBEGIN:
B1_from_BBEGIN:
// (byte) i#2 = (byte) 5 // zpby1=coby1
lda #5
sta 5
jmp B1
B1_from_B1:
// (byte) i#2 = (byte) i#1 // zpby1=zpby2
lda 4
sta 5
B1:
// (byte~) $0 ← (byte) 2 + (byte) i#2 // zpby1=coby1_plus_zpby2
lda #2
clc
adc 5
sta 2
// (byte~) $1 ← (byte~) $0 + (byte) 2 // zpby1=zpby2_plus_coby1
lda 2
clc
adc #2
sta 3
// *((word) 4352 + (byte) i#2) ← (byte~) $1 // ptr_cowo1_zpby1=zpby2
lda 3
ldy 5
sta 4352,y
// (byte) i#1 ← (byte) i#2 + (byte) 1 // zpby1=zpby2_plus_1
lda 5
clc
adc #1
sta 4
// if((byte) i#1<(byte) 10) goto @1 // zpby1_lt_coby1_then_la1
lda 4
cmp #10
bcc B1_from_B1
BEND:

View File

@ -0,0 +1,9 @@
(byte~) $0 zp byte:2
(byte~) $1 zp byte:3
(label) @1
(label) @BEGIN
(label) @END
(byte) i
(byte) i#1 zp byte:4
(byte) i#2 zp byte:5
(byte[16]) p