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

Replaced all program labels with labelrefs ans procedures with procedurerefs.

This commit is contained in:
Jesper Gravgaard 2017-07-20 09:26:06 +02:00
parent e6d09187e3
commit de88808c5f
32 changed files with 284 additions and 185 deletions

View File

@ -135,13 +135,14 @@ public class AsmFragment {
signature.append(bind(conditionalJump.getRValue2())); signature.append(bind(conditionalJump.getRValue2()));
} }
signature.append("_then_"); signature.append("_then_");
Label destination = conditionalJump.getDestination(); LabelRef destination = conditionalJump.getDestination();
ControlFlowBlock destinationBlock = graph.getBlock(destination); ControlFlowBlock destinationBlock = graph.getBlock(destination);
String destinationLabel = destination.getFullName(); String destinationLabel = destination.getFullName();
if (destinationBlock.hasPhiStatements()) { if (destinationBlock.hasPhiStatements()) {
destinationLabel = (destinationBlock.getLabel().getLocalName() + "_from_" + block.getLabel().getLocalName()).replace('@', 'B').replace(':','_'); destinationLabel = (destinationBlock.getLabel().getLocalName() + "_from_" + block.getLabel().getLocalName()).replace('@', 'B').replace(':','_');
} }
signature.append(bind(new Label(destinationLabel, destination.getScope(),false))); Symbol destSymbol = symbols.getSymbol(destination);
signature.append(bind(new Label(destinationLabel, destSymbol.getScope(),false)));
return signature.toString(); return signature.toString();
} }

View File

@ -8,24 +8,24 @@ import java.util.List;
* The block only knows its own successors. To find predecessor blocks access to the entire graph is needed.*/ * The block only knows its own successors. To find predecessor blocks access to the entire graph is needed.*/
public class ControlFlowBlock { public class ControlFlowBlock {
private Label label; private LabelRef label;
private List<Statement> statements; private List<Statement> statements;
private Label defaultSuccessor; private LabelRef defaultSuccessor;
private Label conditionalSuccessor; private LabelRef conditionalSuccessor;
private Label callSuccessor; private LabelRef callSuccessor;
public ControlFlowBlock(Label label) { public ControlFlowBlock(LabelRef label) {
this.label = label; this.label = label;
this.statements = new ArrayList<>(); this.statements = new ArrayList<>();
this.defaultSuccessor = null; this.defaultSuccessor = null;
this.conditionalSuccessor = null; this.conditionalSuccessor = null;
} }
public Label getLabel() { public LabelRef getLabel() {
return label; return label;
} }
@ -33,27 +33,27 @@ public class ControlFlowBlock {
this.statements.add(statement); this.statements.add(statement);
} }
public void setDefaultSuccessor(Label defaultSuccessor) { public void setDefaultSuccessor(LabelRef defaultSuccessor) {
this.defaultSuccessor = defaultSuccessor; this.defaultSuccessor = defaultSuccessor;
} }
public Label getDefaultSuccessor() { public LabelRef getDefaultSuccessor() {
return defaultSuccessor; return defaultSuccessor;
} }
public Label getConditionalSuccessor() { public LabelRef getConditionalSuccessor() {
return conditionalSuccessor; return conditionalSuccessor;
} }
public void setConditionalSuccessor(Label conditionalSuccessor) { public void setConditionalSuccessor(LabelRef conditionalSuccessor) {
this.conditionalSuccessor = conditionalSuccessor; this.conditionalSuccessor = conditionalSuccessor;
} }
public Label getCallSuccessor() { public LabelRef getCallSuccessor() {
return callSuccessor; return callSuccessor;
} }
public void setCallSuccessor(Label callSuccessor) { public void setCallSuccessor(LabelRef callSuccessor) {
this.callSuccessor = callSuccessor; this.callSuccessor = callSuccessor;
} }

View File

@ -6,16 +6,16 @@ import java.util.*;
* The control flow graph is a set of connected basic blocks. */ * The control flow graph is a set of connected basic blocks. */
public class ControlFlowGraph { public class ControlFlowGraph {
private Map<Symbol, ControlFlowBlock> blocks; private Map<SymbolRef, ControlFlowBlock> blocks;
private ControlFlowBlock firstBlock; private ControlFlowBlock firstBlock;
private List<ControlFlowBlock> sequence; private List<ControlFlowBlock> sequence;
public ControlFlowGraph(Map<Symbol, ControlFlowBlock> blocks, ControlFlowBlock firstBlock) { public ControlFlowGraph(Map<SymbolRef, ControlFlowBlock> blocks, ControlFlowBlock firstBlock) {
this.blocks = blocks; this.blocks = blocks;
this.firstBlock = firstBlock; this.firstBlock = firstBlock;
} }
public ControlFlowBlock getBlock(Symbol symbol) { public ControlFlowBlock getBlock(SymbolRef symbol) {
return blocks.get(symbol); return blocks.get(symbol);
} }
@ -106,7 +106,7 @@ public class ControlFlowGraph {
public ControlFlowBlock getMainBlock() { public ControlFlowBlock getMainBlock() {
for (ControlFlowBlock block : getAllBlocks()) { for (ControlFlowBlock block : getAllBlocks()) {
Label label = block.getLabel(); LabelRef label = block.getLabel();
if(label.getFullName().equals("main")) { if(label.getFullName().equals("main")) {
return block; return block;
} }

View File

@ -16,7 +16,7 @@ public class ControlFlowGraphCopyVisitor extends ControlFlowGraphBaseVisitor<Obj
/** /**
* The copied blocks. * The copied blocks.
*/ */
private LinkedHashMap<Symbol, ControlFlowBlock> copyBlockMap; private LinkedHashMap<SymbolRef, ControlFlowBlock> copyBlockMap;
/** /**
* The current block being copied. * The current block being copied.
@ -46,7 +46,7 @@ public class ControlFlowGraphCopyVisitor extends ControlFlowGraphBaseVisitor<Obj
@Override @Override
public ControlFlowBlock visitBlock(ControlFlowBlock origBlock) { public ControlFlowBlock visitBlock(ControlFlowBlock origBlock) {
Label label = origBlock.getLabel(); LabelRef label = origBlock.getLabel();
ControlFlowBlock copyBlock = new ControlFlowBlock(label); ControlFlowBlock copyBlock = new ControlFlowBlock(label);
this.origBlock = origBlock; this.origBlock = origBlock;
this.copyBlock = copyBlock; this.copyBlock = copyBlock;
@ -91,7 +91,7 @@ public class ControlFlowGraphCopyVisitor extends ControlFlowGraphBaseVisitor<Obj
* @param label The label to use for the new block * @param label The label to use for the new block
* @return The new block. * @return The new block.
*/ */
protected ControlFlowBlock splitCurrentBlock(Label label) { protected ControlFlowBlock splitCurrentBlock(LabelRef label) {
ControlFlowBlock newBlock = new ControlFlowBlock(label); ControlFlowBlock newBlock = new ControlFlowBlock(label);
this.copyBlock.setDefaultSuccessor(newBlock.getLabel()); this.copyBlock.setDefaultSuccessor(newBlock.getLabel());
this.copyBlockMap.put(this.copyBlock.getLabel(), this.copyBlock); this.copyBlockMap.put(this.copyBlock.getLabel(), this.copyBlock);
@ -119,7 +119,7 @@ public class ControlFlowGraphCopyVisitor extends ControlFlowGraphBaseVisitor<Obj
StatementPhi copyPhi = new StatementPhi(lValue); StatementPhi copyPhi = new StatementPhi(lValue);
for (StatementPhi.PreviousSymbol origPreviousVersion : phi.getPreviousVersions()) { for (StatementPhi.PreviousSymbol origPreviousVersion : phi.getPreviousVersions()) {
RValue rValue = origPreviousVersion.getRValue(); RValue rValue = origPreviousVersion.getRValue();
Label block = origPreviousVersion.getBlock(); LabelRef block = origPreviousVersion.getBlock();
copyPhi.addPreviousVersion(block, rValue); copyPhi.addPreviousVersion(block, rValue);
} }
return copyPhi; return copyPhi;
@ -139,19 +139,19 @@ public class ControlFlowGraphCopyVisitor extends ControlFlowGraphBaseVisitor<Obj
RValue rValue1 = origConditionalJump.getRValue1(); RValue rValue1 = origConditionalJump.getRValue1();
Operator operator = origConditionalJump.getOperator(); Operator operator = origConditionalJump.getOperator();
RValue rValue2 = origConditionalJump.getRValue2(); RValue rValue2 = origConditionalJump.getRValue2();
Label destination = origConditionalJump.getDestination(); LabelRef destination = origConditionalJump.getDestination();
return new StatementConditionalJump(rValue1, operator, rValue2, destination); return new StatementConditionalJump(rValue1, operator, rValue2, destination);
} }
@Override @Override
public StatementJump visitJump(StatementJump origJump) { public StatementJump visitJump(StatementJump origJump) {
Label destination = origJump.getDestination(); LabelRef destination = origJump.getDestination();
return new StatementJump(destination); return new StatementJump(destination);
} }
@Override @Override
public StatementLabel visitJumpTarget(StatementLabel origJump) { public StatementLabel visitJumpTarget(StatementLabel origJump) {
Label label = origJump.getLabel(); LabelRef label = origJump.getLabel();
return new StatementLabel(label); return new StatementLabel(label);
} }

View File

@ -98,6 +98,7 @@ public class Label implements Symbol {
} }
@Override @Override
@JsonIgnore
public String getAsString() { public String getAsString() {
return getFullName(); return getFullName();
} }
@ -106,4 +107,8 @@ public class Label implements Symbol {
return "("+getType().getTypeName() + ") "+getFullName(); return "("+getType().getTypeName() + ") "+getFullName();
} }
@JsonIgnore
public LabelRef getRef() {
return new LabelRef(this);
}
} }

View File

@ -0,0 +1,14 @@
package dk.camelot64.kickc.icl;
/** A reference to a label */
public class LabelRef extends SymbolRef {
public LabelRef(String fullName) {
super(fullName);
}
public LabelRef(Label label) {
super(label.getFullName());
}
}

View File

@ -124,7 +124,13 @@ public class Procedure extends Scope {
} }
@Override @Override
@JsonIgnore
public String getAsString() { public String getAsString() {
return getTypedName(); return getTypedName();
} }
@JsonIgnore
public ProcedureRef getRef() {
return new ProcedureRef(this.getFullName());
}
} }

View File

@ -0,0 +1,13 @@
package dk.camelot64.kickc.icl;
/** A reference to a procedure */
public class ProcedureRef extends SymbolRef {
public ProcedureRef(String fullName) {
super(fullName);
}
public LabelRef getLabelRef() {
return new LabelRef(getFullName());
}
}

View File

@ -1,6 +1,7 @@
package dk.camelot64.kickc.icl; package dk.camelot64.kickc.icl;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.HashMap; import java.util.HashMap;
@ -77,6 +78,7 @@ public class ProgramScope extends Scope {
} }
@Override @Override
@JsonIgnore
public String getAsString() { public String getAsString() {
return "program"; return "program";
} }

View File

@ -121,6 +121,10 @@ public abstract class Scope implements Symbol {
return symbol; return symbol;
} }
public Symbol getSymbol(SymbolRef symbolRef) {
return getSymbol(symbolRef.getFullName());
}
public Symbol getSymbol(String name) { public Symbol getSymbol(String name) {
int pos = name.indexOf("::"); int pos = name.indexOf("::");
if (pos >= 0) { if (pos >= 0) {
@ -181,6 +185,10 @@ public abstract class Scope implements Symbol {
return (Label) symbols.get(name); return (Label) symbols.get(name);
} }
public Label getLabel(LabelRef labelRef) {
return (Label) symbols.get(labelRef);
}
public Procedure addProcedure(String name, SymbolType type) { public Procedure addProcedure(String name, SymbolType type) {
Symbol symbol = symbols.get(name); Symbol symbol = symbols.get(name);
if (symbol != null) { if (symbol != null) {

View File

@ -12,8 +12,8 @@ public class StatementCall implements StatementLValue {
/** The variable being assigned a value by the call. Can be null. */ /** The variable being assigned a value by the call. Can be null. */
private LValue lValue; private LValue lValue;
private String procedureName; private String procedureName;
private ProcedureRef procedure;
private List<RValue> parameters; private List<RValue> parameters;
private Procedure procedure;
private boolean parametersByAssignment; private boolean parametersByAssignment;
public StatementCall(LValue lValue, String procedureName, List<RValue> parameters) { public StatementCall(LValue lValue, String procedureName, List<RValue> parameters) {
@ -35,11 +35,11 @@ public class StatementCall implements StatementLValue {
return procedureName; return procedureName;
} }
public Procedure getProcedure() { public ProcedureRef getProcedure() {
return procedure; return procedure;
} }
public void setProcedure(Procedure procedure) { public void setProcedure(ProcedureRef procedure) {
this.procedure = procedure; this.procedure = procedure;
} }

View File

@ -14,16 +14,16 @@ public class StatementConditionalJump implements Statement {
private RValue rValue1; private RValue rValue1;
private Operator operator; private Operator operator;
private RValue rValue2; private RValue rValue2;
private Label destination; private LabelRef destination;
public StatementConditionalJump(RValue condition, Label destination) { public StatementConditionalJump(RValue condition, LabelRef destination) {
this.rValue1 = null; this.rValue1 = null;
this.operator = null; this.operator = null;
this.rValue2 = condition; this.rValue2 = condition;
this.destination = destination; this.destination = destination;
} }
public StatementConditionalJump(RValue rValue1, Operator operator, RValue rValue2, Label destination) { public StatementConditionalJump(RValue rValue1, Operator operator, RValue rValue2, LabelRef destination) {
this.rValue1 = rValue1; this.rValue1 = rValue1;
this.operator = operator; this.operator = operator;
this.rValue2 = rValue2; this.rValue2 = rValue2;
@ -42,7 +42,7 @@ public class StatementConditionalJump implements Statement {
return rValue2; return rValue2;
} }
public Label getDestination() { public LabelRef getDestination() {
return destination; return destination;
} }
@ -58,7 +58,7 @@ public class StatementConditionalJump implements Statement {
this.rValue2 = rValue2; this.rValue2 = rValue2;
} }
public void setDestination(Label destination) { public void setDestination(LabelRef destination) {
this.destination = destination; this.destination = destination;
} }

View File

@ -8,17 +8,17 @@ package dk.camelot64.kickc.icl;
*/ */
public class StatementJump implements Statement { public class StatementJump implements Statement {
private Label destination; private LabelRef destination;
public StatementJump(Label destination) { public StatementJump(LabelRef destination) {
this.destination = destination; this.destination = destination;
} }
public Label getDestination() { public LabelRef getDestination() {
return destination; return destination;
} }
public void setDestination(Label destination) { public void setDestination(LabelRef destination) {
this.destination = destination; this.destination = destination;
} }
@ -34,5 +34,7 @@ public class StatementJump implements Statement {
@Override @Override
public String getAsString() { public String getAsString() {
return "goto "+destination.getFullName(); } return "goto "+destination.getFullName();
}
} }

View File

@ -5,13 +5,13 @@ package dk.camelot64.kickc.icl;
*/ */
public class StatementLabel implements Statement { public class StatementLabel implements Statement {
private Label label; private LabelRef label;
public StatementLabel(Label label) { public StatementLabel(LabelRef label) {
this.label = label; this.label = label;
} }
public Label getLabel() { public LabelRef getLabel() {
return label; return label;
} }

View File

@ -31,15 +31,15 @@ public class StatementPhi implements StatementLValue {
* Which value is chosen depends on which block transition was made. * Which value is chosen depends on which block transition was made.
*/ */
public static class PreviousSymbol { public static class PreviousSymbol {
private Label block; private LabelRef block;
private RValue rValue; private RValue rValue;
public PreviousSymbol(Label block, RValue rValue) { public PreviousSymbol(LabelRef block, RValue rValue) {
this.block = block; this.block = block;
this.rValue = rValue; this.rValue = rValue;
} }
public Label getBlock() { public LabelRef getBlock() {
return block; return block;
} }
@ -51,7 +51,7 @@ public class StatementPhi implements StatementLValue {
this.rValue = RValue; this.rValue = RValue;
} }
public void setBlock(Label block) { public void setBlock(LabelRef block) {
this.block = block; this.block = block;
} }
} }
@ -68,7 +68,7 @@ public class StatementPhi implements StatementLValue {
this.lValue = (VariableRef) lValue; this.lValue = (VariableRef) lValue;
} }
public void addPreviousVersion(Label block, RValue rValue) { public void addPreviousVersion(LabelRef block, RValue rValue) {
previousVersions.add(new PreviousSymbol(block, rValue)); previousVersions.add(new PreviousSymbol(block, rValue));
} }

View File

@ -3,7 +3,7 @@ package dk.camelot64.kickc.icl;
/** Procedure declaration in SSA */ /** Procedure declaration in SSA */
public class StatementProcedureBegin implements Statement { public class StatementProcedureBegin implements Statement {
private Procedure procedure; private ProcedureRef procedure;
private Strategy strategy; private Strategy strategy;
@ -12,11 +12,11 @@ public class StatementProcedureBegin implements Statement {
INLINE INLINE
} }
public StatementProcedureBegin(Procedure procedure) { public StatementProcedureBegin(ProcedureRef procedure) {
this.procedure = procedure; this.procedure = procedure;
} }
public Procedure getProcedure() { public ProcedureRef getProcedure() {
return procedure; return procedure;
} }

View File

@ -3,13 +3,13 @@ package dk.camelot64.kickc.icl;
/** Procedure declaration in SSA */ /** Procedure declaration in SSA */
public class StatementProcedureEnd implements Statement { public class StatementProcedureEnd implements Statement {
private Procedure procedure; private ProcedureRef procedure;
public StatementProcedureEnd(Procedure procedure) { public StatementProcedureEnd(ProcedureRef procedure) {
this.procedure = procedure; this.procedure = procedure;
} }
public Procedure getProcedure() { public ProcedureRef getProcedure() {
return procedure; return procedure;
} }

View File

@ -0,0 +1,93 @@
package dk.camelot64.kickc.icl;
import com.fasterxml.jackson.annotation.JsonIgnore;
/** A reference to a symbol (variable, procedure or label) */
public class SymbolRef implements Value {
/** The full name of the variable. Allowing lookup in the symbol table. */
private String fullName;
public SymbolRef(String fullName) {
this.fullName = fullName;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
SymbolRef symbolRef = (SymbolRef) o;
return fullName != null ? fullName.equals(symbolRef.fullName) : symbolRef.fullName == null;
}
@Override
public int hashCode() {
return fullName != null ? fullName.hashCode() : 0;
}
@Override
public String getAsTypedString(ProgramScope scope) {
return scope.getSymbol(fullName).getTypedName();
}
@Override
@JsonIgnore
public String getAsString() {
return fullName;
}
@JsonIgnore
public int getScopeDepth() {
int depth = 0;
char[] chars = fullName.toCharArray();
for (char c : chars) {
if(c==':') depth++;
}
return depth/2;
}
@JsonIgnore
public boolean isVersion() {
return fullName.contains("#");
}
@JsonIgnore
public boolean isIntermediate() {
if(fullName.contains("@BEGIN") || fullName.contains("@END") ) return false;
return fullName.contains("$") || fullName.contains("@");
}
@JsonIgnore
public String getLocalName() {
int lastScopeIdx = fullName.lastIndexOf("::");
if(lastScopeIdx==-1) {
return fullName;
} else {
return fullName.substring(lastScopeIdx+2);
}
}
@JsonIgnore
public String getScopeNames() {
int lastScopeIdx = fullName.lastIndexOf("::");
if(lastScopeIdx==-1) {
return "";
} else {
return fullName.substring(0, lastScopeIdx);
}
}
}

View File

@ -129,6 +129,7 @@ public abstract class Variable implements Symbol {
} }
@Override @Override
@JsonIgnore
public String getAsString() { public String getAsString() {
return getTypedName(); return getTypedName();
} }

View File

@ -1,59 +1,14 @@
package dk.camelot64.kickc.icl; package dk.camelot64.kickc.icl;
/** A reference to a variable from the symbol table */ /** A reference to a variable from the symbol table */
public class VariableRef implements RValue, LValue { public class VariableRef extends SymbolRef implements RValue, LValue {
/** The full name of the variable. Allowing lookup in the symbol table. */
private String fullName;
public VariableRef(String fullName) { public VariableRef(String fullName) {
this.fullName = fullName; super(fullName);
} }
public VariableRef(Variable variable) { public VariableRef(Variable variable) {
this(variable.getFullName()); this(variable.getFullName());
} }
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
VariableRef that = (VariableRef) o;
return fullName != null ? fullName.equals(that.fullName) : that.fullName == null;
}
@Override
public int hashCode() {
return fullName != null ? fullName.hashCode() : 0;
}
@Override
public String toString() {
return getAsString();
}
@Override
public String getAsTypedString(ProgramScope scope) {
Variable variable = scope.getVariable(this);
return variable.getTypedName();
}
@Override
public String getAsString() {
return fullName;
}
} }

View File

@ -12,7 +12,7 @@ public class Pass1GenerateControlFlowGraph {
public static final String BEGIN_BLOCK_NAME = "@BEGIN"; public static final String BEGIN_BLOCK_NAME = "@BEGIN";
public static final String END_BLOCK_NAME = "@END"; public static final String END_BLOCK_NAME = "@END";
private Scope scope; private Scope scope;
private Map<Symbol, ControlFlowBlock> blocks; private Map<SymbolRef, ControlFlowBlock> blocks;
private ControlFlowBlock firstBlock; private ControlFlowBlock firstBlock;
public Pass1GenerateControlFlowGraph(Scope scope) { public Pass1GenerateControlFlowGraph(Scope scope) {
@ -21,10 +21,10 @@ public class Pass1GenerateControlFlowGraph {
} }
public ControlFlowGraph generate(StatementSequence sequence) { public ControlFlowGraph generate(StatementSequence sequence) {
this.firstBlock = getOrCreateBlock(scope.addLabel(BEGIN_BLOCK_NAME)); this.firstBlock = getOrCreateBlock(scope.addLabel(BEGIN_BLOCK_NAME).getRef());
Stack<ControlFlowBlock> blockStack = new Stack<>(); Stack<ControlFlowBlock> blockStack = new Stack<>();
blockStack.push(firstBlock); blockStack.push(firstBlock);
sequence.addStatement(new StatementLabel(scope.addLabel(END_BLOCK_NAME))); sequence.addStatement(new StatementLabel(scope.addLabel(END_BLOCK_NAME).getRef()));
for (Statement statement : sequence.getStatements()) { for (Statement statement : sequence.getStatements()) {
ControlFlowBlock currentBlock = blockStack.peek(); ControlFlowBlock currentBlock = blockStack.peek();
if(statement instanceof StatementLabel) { if(statement instanceof StatementLabel) {
@ -37,14 +37,14 @@ public class Pass1GenerateControlFlowGraph {
StatementJump statementJump = (StatementJump) statement; StatementJump statementJump = (StatementJump) statement;
ControlFlowBlock jmpBlock = getOrCreateBlock(statementJump.getDestination()); ControlFlowBlock jmpBlock = getOrCreateBlock(statementJump.getDestination());
currentBlock.setDefaultSuccessor(jmpBlock.getLabel()); currentBlock.setDefaultSuccessor(jmpBlock.getLabel());
ControlFlowBlock nextBlock = getOrCreateBlock(scope.addLabelIntermediate()); ControlFlowBlock nextBlock = getOrCreateBlock(scope.addLabelIntermediate().getRef());
blockStack.pop(); blockStack.pop();
blockStack.push(nextBlock); blockStack.push(nextBlock);
} else if(statement instanceof StatementConditionalJump) { } else if(statement instanceof StatementConditionalJump) {
currentBlock.addStatement(statement); currentBlock.addStatement(statement);
StatementConditionalJump statementConditionalJump = (StatementConditionalJump) statement; StatementConditionalJump statementConditionalJump = (StatementConditionalJump) statement;
ControlFlowBlock jmpBlock = getOrCreateBlock(statementConditionalJump.getDestination()); ControlFlowBlock jmpBlock = getOrCreateBlock(statementConditionalJump.getDestination());
ControlFlowBlock nextBlock = getOrCreateBlock(scope.addLabelIntermediate()); ControlFlowBlock nextBlock = getOrCreateBlock(scope.addLabelIntermediate().getRef());
currentBlock.setDefaultSuccessor(nextBlock.getLabel()); currentBlock.setDefaultSuccessor(nextBlock.getLabel());
currentBlock.setConditionalSuccessor(jmpBlock.getLabel()); currentBlock.setConditionalSuccessor(jmpBlock.getLabel());
blockStack.pop(); blockStack.pop();
@ -53,13 +53,14 @@ public class Pass1GenerateControlFlowGraph {
// Procedure strategy implemented is currently variable-based transfer of parameters/return values // Procedure strategy implemented is currently variable-based transfer of parameters/return values
StatementProcedureBegin procedureBegin = (StatementProcedureBegin) statement; StatementProcedureBegin procedureBegin = (StatementProcedureBegin) statement;
procedureBegin.setStrategy(StatementProcedureBegin.Strategy.PASS_BY_REGISTER); procedureBegin.setStrategy(StatementProcedureBegin.Strategy.PASS_BY_REGISTER);
Label procedureLabel = procedureBegin.getProcedure().getLabel(); ProcedureRef procedureRef = procedureBegin.getProcedure();
ControlFlowBlock procBlock = getOrCreateBlock(procedureLabel); LabelRef procedureLabelRef = procedureRef.getLabelRef();
ControlFlowBlock procBlock = getOrCreateBlock(procedureLabelRef);
blockStack.push(procBlock); blockStack.push(procBlock);
} else if(statement instanceof StatementProcedureEnd) { } else if(statement instanceof StatementProcedureEnd) {
// Procedure strategy implemented is currently variable-based transfer of parameters/return values // Procedure strategy implemented is currently variable-based transfer of parameters/return values
currentBlock.setDefaultSuccessor(new Label("@RETURN", scope, false)); currentBlock.setDefaultSuccessor(new Label("@RETURN", scope, false).getRef());
ControlFlowBlock nextBlock = getOrCreateBlock(scope.addLabelIntermediate()); ControlFlowBlock nextBlock = getOrCreateBlock(scope.addLabelIntermediate().getRef());
blockStack.pop(); blockStack.pop();
ControlFlowBlock prevBlock = blockStack.pop(); ControlFlowBlock prevBlock = blockStack.pop();
prevBlock.setDefaultSuccessor(nextBlock.getLabel()); prevBlock.setDefaultSuccessor(nextBlock.getLabel());
@ -77,7 +78,7 @@ public class Pass1GenerateControlFlowGraph {
return new ControlFlowGraph(blocks, firstBlock); return new ControlFlowGraph(blocks, firstBlock);
} }
private ControlFlowBlock getOrCreateBlock(Label label) { private ControlFlowBlock getOrCreateBlock(LabelRef label) {
ControlFlowBlock block = blocks.get(label); ControlFlowBlock block = blocks.get(label);
if(block==null) { if(block==null) {
block = new ControlFlowBlock(label); block = new ControlFlowBlock(label);

View File

@ -170,8 +170,8 @@ public class Pass1GenerateSingleStaticAssignmentForm {
* false if new phis were added, meaning another iteration is needed. * false if new phis were added, meaning another iteration is needed.
*/ */
private boolean completePhiFunctions() { private boolean completePhiFunctions() {
Map<Label, Map<VariableUnversioned, VariableVersion>> newPhis = new LinkedHashMap<>(); Map<LabelRef, Map<VariableUnversioned, VariableVersion>> newPhis = new LinkedHashMap<>();
Map<Label, Map<VariableUnversioned, VariableVersion>> symbolMap = buildSymbolMap(); Map<LabelRef, Map<VariableUnversioned, VariableVersion>> symbolMap = buildSymbolMap();
for (ControlFlowBlock block : this.controlFlowGraph.getAllBlocks()) { for (ControlFlowBlock block : this.controlFlowGraph.getAllBlocks()) {
for (Statement statement : block.getStatements()) { for (Statement statement : block.getStatements()) {
if (statement instanceof StatementPhi) { if (statement instanceof StatementPhi) {
@ -181,7 +181,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
VariableVersion versioned = (VariableVersion) symbols.getVariable(phiLValVarRef); VariableVersion versioned = (VariableVersion) symbols.getVariable(phiLValVarRef);
VariableUnversioned unversioned = versioned.getVersionOf(); VariableUnversioned unversioned = versioned.getVersionOf();
for (ControlFlowBlock predecessor : controlFlowGraph.getPredecessors(block)) { for (ControlFlowBlock predecessor : controlFlowGraph.getPredecessors(block)) {
Label predecessorLabel = predecessor.getLabel(); LabelRef predecessorLabel = predecessor.getLabel();
Map<VariableUnversioned, VariableVersion> predecessorMap = symbolMap.get(predecessorLabel); Map<VariableUnversioned, VariableVersion> predecessorMap = symbolMap.get(predecessorLabel);
VariableVersion previousSymbol = null; VariableVersion previousSymbol = null;
if (predecessorMap != null) { if (predecessorMap != null) {
@ -223,8 +223,8 @@ public class Pass1GenerateSingleStaticAssignmentForm {
* Builds a map of all which versions each symbol has in each block. * Builds a map of all which versions each symbol has in each block.
* Maps Control Flow Block Label -> ( Unversioned Symbol -> Versioned Symbol) for all relevant symbols. * Maps Control Flow Block Label -> ( Unversioned Symbol -> Versioned Symbol) for all relevant symbols.
*/ */
private Map<Label, Map<VariableUnversioned, VariableVersion>> buildSymbolMap() { private Map<LabelRef, Map<VariableUnversioned, VariableVersion>> buildSymbolMap() {
Map<Label, Map<VariableUnversioned, VariableVersion>> symbolMap = new LinkedHashMap<>(); Map<LabelRef, Map<VariableUnversioned, VariableVersion>> symbolMap = new LinkedHashMap<>();
for (ControlFlowBlock block : this.controlFlowGraph.getAllBlocks()) { for (ControlFlowBlock block : this.controlFlowGraph.getAllBlocks()) {
for (Statement statement : block.getStatements()) { for (Statement statement : block.getStatements()) {
if (statement instanceof StatementLValue) { if (statement instanceof StatementLValue) {
@ -234,7 +234,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
Variable lValueVar = symbols.getVariable((VariableRef) lValue); Variable lValueVar = symbols.getVariable((VariableRef) lValue);
if (lValueVar instanceof VariableVersion) { if (lValueVar instanceof VariableVersion) {
VariableVersion versioned = (VariableVersion) lValueVar; VariableVersion versioned = (VariableVersion) lValueVar;
Label label = block.getLabel(); LabelRef label = block.getLabel();
VariableUnversioned unversioned = versioned.getVersionOf(); VariableUnversioned unversioned = versioned.getVersionOf();
Map<VariableUnversioned, VariableVersion> blockMap = symbolMap.get(label); Map<VariableUnversioned, VariableVersion> blockMap = symbolMap.get(label);
if (blockMap == null) { if (blockMap == null) {

View File

@ -88,25 +88,25 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
PrePostModifierHandler.addPostModifiers(this, ctx.expr()); PrePostModifierHandler.addPostModifiers(this, ctx.expr());
Label ifJumpLabel = getCurrentSymbols().addLabelIntermediate(); Label ifJumpLabel = getCurrentSymbols().addLabelIntermediate();
Label elseJumpLabel = getCurrentSymbols().addLabelIntermediate(); Label elseJumpLabel = getCurrentSymbols().addLabelIntermediate();
Statement ifJmpStmt = new StatementConditionalJump(rValue, ifJumpLabel); Statement ifJmpStmt = new StatementConditionalJump(rValue, ifJumpLabel.getRef());
sequence.addStatement(ifJmpStmt); sequence.addStatement(ifJmpStmt);
Statement elseJmpStmt = new StatementJump(elseJumpLabel); Statement elseJmpStmt = new StatementJump(elseJumpLabel.getRef());
sequence.addStatement(elseJmpStmt); sequence.addStatement(elseJmpStmt);
StatementLabel ifJumpTarget = new StatementLabel(ifJumpLabel); StatementLabel ifJumpTarget = new StatementLabel(ifJumpLabel.getRef());
sequence.addStatement(ifJumpTarget); sequence.addStatement(ifJumpTarget);
this.visit(ctx.stmt(0)); this.visit(ctx.stmt(0));
KickCParser.StmtContext elseStmt = ctx.stmt(1); KickCParser.StmtContext elseStmt = ctx.stmt(1);
if (elseStmt != null) { if (elseStmt != null) {
Label endJumpLabel = getCurrentSymbols().addLabelIntermediate(); Label endJumpLabel = getCurrentSymbols().addLabelIntermediate();
Statement endJmpStmt = new StatementJump(endJumpLabel); Statement endJmpStmt = new StatementJump(endJumpLabel.getRef());
sequence.addStatement(endJmpStmt); sequence.addStatement(endJmpStmt);
StatementLabel elseJumpTarget = new StatementLabel(elseJumpLabel); StatementLabel elseJumpTarget = new StatementLabel(elseJumpLabel.getRef());
sequence.addStatement(elseJumpTarget); sequence.addStatement(elseJumpTarget);
this.visit(elseStmt); this.visit(elseStmt);
StatementLabel endJumpTarget = new StatementLabel(endJumpLabel); StatementLabel endJumpTarget = new StatementLabel(endJumpLabel.getRef());
sequence.addStatement(endJumpTarget); sequence.addStatement(endJumpTarget);
} else { } else {
StatementLabel elseJumpTarget = new StatementLabel(elseJumpLabel); StatementLabel elseJumpTarget = new StatementLabel(elseJumpLabel.getRef());
sequence.addStatement(elseJumpTarget); sequence.addStatement(elseJumpTarget);
} }
return null; return null;
@ -117,21 +117,21 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
Label beginJumpLabel = getCurrentSymbols().addLabelIntermediate(); Label beginJumpLabel = getCurrentSymbols().addLabelIntermediate();
Label doJumpLabel = getCurrentSymbols().addLabelIntermediate(); Label doJumpLabel = getCurrentSymbols().addLabelIntermediate();
Label endJumpLabel = getCurrentSymbols().addLabelIntermediate(); Label endJumpLabel = getCurrentSymbols().addLabelIntermediate();
StatementLabel beginJumpTarget = new StatementLabel(beginJumpLabel); StatementLabel beginJumpTarget = new StatementLabel(beginJumpLabel.getRef());
sequence.addStatement(beginJumpTarget); sequence.addStatement(beginJumpTarget);
PrePostModifierHandler.addPreModifiers(this, ctx.expr()); PrePostModifierHandler.addPreModifiers(this, ctx.expr());
RValue rValue = (RValue) this.visit(ctx.expr()); RValue rValue = (RValue) this.visit(ctx.expr());
PrePostModifierHandler.addPostModifiers(this, ctx.expr()); PrePostModifierHandler.addPostModifiers(this, ctx.expr());
Statement doJmpStmt = new StatementConditionalJump(rValue, doJumpLabel); Statement doJmpStmt = new StatementConditionalJump(rValue, doJumpLabel.getRef());
sequence.addStatement(doJmpStmt); sequence.addStatement(doJmpStmt);
Statement endJmpStmt = new StatementJump(endJumpLabel); Statement endJmpStmt = new StatementJump(endJumpLabel.getRef());
sequence.addStatement(endJmpStmt); sequence.addStatement(endJmpStmt);
StatementLabel doJumpTarget = new StatementLabel(doJumpLabel); StatementLabel doJumpTarget = new StatementLabel(doJumpLabel.getRef());
sequence.addStatement(doJumpTarget); sequence.addStatement(doJumpTarget);
this.visit(ctx.stmt()); this.visit(ctx.stmt());
Statement beginJmpStmt = new StatementJump(beginJumpLabel); Statement beginJmpStmt = new StatementJump(beginJumpLabel.getRef());
sequence.addStatement(beginJmpStmt); sequence.addStatement(beginJmpStmt);
StatementLabel endJumpTarget = new StatementLabel(endJumpLabel); StatementLabel endJumpTarget = new StatementLabel(endJumpLabel.getRef());
sequence.addStatement(endJumpTarget); sequence.addStatement(endJumpTarget);
return null; return null;
} }
@ -139,7 +139,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
@Override @Override
public Void visitStmtDoWhile(KickCParser.StmtDoWhileContext ctx) { public Void visitStmtDoWhile(KickCParser.StmtDoWhileContext ctx) {
Label beginJumpLabel = getCurrentSymbols().addLabelIntermediate(); Label beginJumpLabel = getCurrentSymbols().addLabelIntermediate();
StatementLabel beginJumpTarget = new StatementLabel(beginJumpLabel); StatementLabel beginJumpTarget = new StatementLabel(beginJumpLabel.getRef());
sequence.addStatement(beginJumpTarget); sequence.addStatement(beginJumpTarget);
if (ctx.stmt() != null) { if (ctx.stmt() != null) {
this.visit(ctx.stmt()); this.visit(ctx.stmt());
@ -147,7 +147,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
PrePostModifierHandler.addPreModifiers(this, ctx.expr()); PrePostModifierHandler.addPreModifiers(this, ctx.expr());
RValue rValue = (RValue) this.visit(ctx.expr()); RValue rValue = (RValue) this.visit(ctx.expr());
PrePostModifierHandler.addPostModifiers(this, ctx.expr()); PrePostModifierHandler.addPostModifiers(this, ctx.expr());
Statement doJmpStmt = new StatementConditionalJump(rValue, beginJumpLabel); Statement doJmpStmt = new StatementConditionalJump(rValue, beginJumpLabel.getRef());
sequence.addStatement(doJmpStmt); sequence.addStatement(doJmpStmt);
return null; return null;
} }
@ -168,11 +168,11 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
parameterList = (List<Variable>) this.visit(ctx.parameterListDecl()); parameterList = (List<Variable>) this.visit(ctx.parameterListDecl());
} }
procedure.setParameters(parameterList); procedure.setParameters(parameterList);
sequence.addStatement(new StatementProcedureBegin(procedure)); sequence.addStatement(new StatementProcedureBegin(procedure.getRef()));
if (ctx.stmtSeq() != null) { if (ctx.stmtSeq() != null) {
this.visit(ctx.stmtSeq()); this.visit(ctx.stmtSeq());
} }
sequence.addStatement(new StatementLabel(procExit)); sequence.addStatement(new StatementLabel(procExit.getRef()));
if (returnVar != null) { if (returnVar != null) {
sequence.addStatement(new StatementAssignment(returnVar, returnVar)); sequence.addStatement(new StatementAssignment(returnVar, returnVar));
} }
@ -180,7 +180,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
if(returnVar!=null) {new VariableRef(returnVar); } if(returnVar!=null) {new VariableRef(returnVar); }
sequence.addStatement(new StatementReturn(returnVarRef)); sequence.addStatement(new StatementReturn(returnVarRef));
scopeStack.pop(); scopeStack.pop();
sequence.addStatement(new StatementProcedureEnd(procedure)); sequence.addStatement(new StatementProcedureEnd(procedure.getRef()));
return null; return null;
} }
@ -214,7 +214,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
PrePostModifierHandler.addPostModifiers(this, exprCtx); PrePostModifierHandler.addPostModifiers(this, exprCtx);
} }
Label returnLabel = procedure.getLabel("@return"); Label returnLabel = procedure.getLabel("@return");
sequence.addStatement(new StatementJump(returnLabel)); sequence.addStatement(new StatementJump(returnLabel.getRef()));
return null; return null;
} }
@ -261,7 +261,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
public LValue visitLvaluePtr(KickCParser.LvaluePtrContext ctx) { public LValue visitLvaluePtr(KickCParser.LvaluePtrContext ctx) {
LValue lval = (LValue) visit(ctx.lvalue()); LValue lval = (LValue) visit(ctx.lvalue());
if (lval instanceof VariableRef) { if (lval instanceof VariableRef) {
return new PointerDereferenceSimple((VariableRef) lval); return new PointerDereferenceSimple(lval);
} else { } else {
throw new RuntimeException("Not implemented"); throw new RuntimeException("Not implemented");
} }

View File

@ -24,7 +24,8 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
public StatementCall visitCall(StatementCall origCall) { public StatementCall visitCall(StatementCall origCall) {
// Procedure strategy implemented is currently variable-based transfer of parameters/return values // Procedure strategy implemented is currently variable-based transfer of parameters/return values
// Generate parameter passing assignments // Generate parameter passing assignments
Procedure procedure = origCall.getProcedure(); ProcedureRef procedureRef = origCall.getProcedure();
Procedure procedure = (Procedure) scope.getSymbol(procedureRef);
List<Variable> parameterDecls = procedure.getParameters(); List<Variable> parameterDecls = procedure.getParameters();
List<RValue> parameterValues = origCall.getParameters(); List<RValue> parameterValues = origCall.getParameters();
for (int i = 0; i < parameterDecls.size(); i++) { for (int i = 0; i < parameterDecls.size(); i++) {
@ -35,13 +36,15 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
String procedureName = origCall.getProcedureName(); String procedureName = origCall.getProcedureName();
Variable procReturnVar = procedure.getVariable("return"); Variable procReturnVar = procedure.getVariable("return");
VariableRef procReturnVarRef = null; VariableRef procReturnVarRef = null;
if(procReturnVar!=null) {new VariableRef(procReturnVar); } if (procReturnVar != null) {
procReturnVarRef = new VariableRef(procReturnVar);
}
StatementCall copyCall = new StatementCall(procReturnVarRef, procedureName, null); StatementCall copyCall = new StatementCall(procReturnVarRef, procedureName, null);
copyCall.setParametersByAssignment(true); copyCall.setParametersByAssignment(true);
copyCall.setProcedure(procedure); copyCall.setProcedure(procedureRef);
addStatementToCurrentBlock(copyCall); addStatementToCurrentBlock(copyCall);
getCurrentBlock().setCallSuccessor(procedure.getLabel()); getCurrentBlock().setCallSuccessor(procedure.getLabel().getRef());
splitCurrentBlock(scope.addLabelIntermediate()); splitCurrentBlock(scope.addLabelIntermediate().getRef());
if(!SymbolTypeBasic.VOID.equals(procedure.getReturnType())) { if(!SymbolTypeBasic.VOID.equals(procedure.getReturnType())) {
addStatementToCurrentBlock(new StatementAssignment(origCall.getlValue(), procReturnVarRef)); addStatementToCurrentBlock(new StatementAssignment(origCall.getlValue(), procReturnVarRef));
} else { } else {

View File

@ -5,10 +5,10 @@ import dk.camelot64.kickc.icl.*;
/** Pass that modifies a control flow graph to call procedures by passing return value through registers */ /** Pass that modifies a control flow graph to call procedures by passing return value through registers */
public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor { public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor {
private Scope scope; private ProgramScope scope;
private ControlFlowGraph graph; private ControlFlowGraph graph;
public Pass1ProcedureCallsReturnValue(Scope scope, ControlFlowGraph graph) { public Pass1ProcedureCallsReturnValue(ProgramScope scope, ControlFlowGraph graph) {
this.scope = scope; this.scope = scope;
this.graph = graph; this.graph = graph;
} }
@ -22,18 +22,19 @@ public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor
public StatementCall visitCall(StatementCall origCall) { public StatementCall visitCall(StatementCall origCall) {
// Procedure strategy implemented is currently variable-based transfer of parameters/return values // Procedure strategy implemented is currently variable-based transfer of parameters/return values
// Generate return value assignment // Generate return value assignment
Procedure procedure = origCall.getProcedure(); ProcedureRef procedureRef = origCall.getProcedure();
Procedure procedure = (Procedure) scope.getSymbol(procedureRef);
String procedureName = origCall.getProcedureName(); String procedureName = origCall.getProcedureName();
StatementCall copyCall = new StatementCall(null, procedureName, null); StatementCall copyCall = new StatementCall(null, procedureName, null);
copyCall.setParametersByAssignment(true); copyCall.setParametersByAssignment(true);
copyCall.setProcedure(procedure); copyCall.setProcedure(procedureRef);
addStatementToCurrentBlock(copyCall); addStatementToCurrentBlock(copyCall);
getCurrentBlock().setCallSuccessor(procedure.getLabel()); getCurrentBlock().setCallSuccessor(procedure.getLabel().getRef());
if(!SymbolTypeBasic.VOID.equals(procedure.getReturnType())) { if(!SymbolTypeBasic.VOID.equals(procedure.getReturnType())) {
// Find return variable final version // Find return variable final version
Label returnBlockLabel = procedure.getLabel("@return"); Label returnBlockLabel = procedure.getLabel("@return");
ControlFlowBlock returnBlock = graph.getBlock(returnBlockLabel); ControlFlowBlock returnBlock = graph.getBlock(returnBlockLabel.getRef());
VariableRef returnVarFinal = null; VariableRef returnVarFinal = null;
for (Statement statement : returnBlock.getStatements()) { for (Statement statement : returnBlock.getStatements()) {
if (statement instanceof StatementReturn) { if (statement instanceof StatementReturn) {

View File

@ -22,7 +22,9 @@ public class Pass1TypeInference {
for (Statement statement : sequence.getStatements()) { for (Statement statement : sequence.getStatements()) {
if(statement instanceof StatementProcedureBegin) { if(statement instanceof StatementProcedureBegin) {
StatementProcedureBegin procedureBegin = (StatementProcedureBegin) statement; StatementProcedureBegin procedureBegin = (StatementProcedureBegin) statement;
scopes.push(procedureBegin.getProcedure()); ProcedureRef procedureRef = procedureBegin.getProcedure();
Procedure procedure = (Procedure) programScope.getSymbol(procedureRef);
scopes.push(procedure);
} else if(statement instanceof StatementProcedureEnd) { } else if(statement instanceof StatementProcedureEnd) {
scopes.pop(); scopes.pop();
} else if (statement instanceof StatementAssignment) { } else if (statement instanceof StatementAssignment) {
@ -54,7 +56,7 @@ public class Pass1TypeInference {
if(lValue instanceof VariableRef) { if(lValue instanceof VariableRef) {
String procedureName = call.getProcedureName(); String procedureName = call.getProcedureName();
Procedure procedure = scopes.peek().getProcedure(procedureName); Procedure procedure = scopes.peek().getProcedure(procedureName);
call.setProcedure(procedure); call.setProcedure(procedure.getRef());
if(procedure.getParameters().size()!=call.getParameters().size()) { if(procedure.getParameters().size()!=call.getParameters().size()) {
throw new RuntimeException("Wrong number of parameters in call. Expected " +procedure.getParameters().size()+". "+statement.toString()); throw new RuntimeException("Wrong number of parameters in call. Expected " +procedure.getParameters().size()+". "+statement.toString());
} }

View File

@ -179,9 +179,9 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
if (keep == null) { if (keep == null) {
keep = var; keep = var;
} else { } else {
if (isVersion(var)) { if (var.isVersion()) {
if (isVersion(keep)) { if (keep.isVersion()) {
if (getScopeDepth(var) < getScopeDepth(keep)) { if (var.getScopeDepth() < keep.getScopeDepth()) {
keep = var; keep = var;
} }
} else { } else {
@ -193,19 +193,6 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
return keep; return keep;
} }
private int getScopeDepth(VariableRef var) {
int depth = 0;
char[] chars = var.getFullName().toCharArray();
for (char c : chars) {
if(c==':') depth++;
}
return depth/2;
}
private boolean isVersion(VariableRef var) {
return var.getFullName().contains("#");
}
public List<VariableRef> getEliminateVars() { public List<VariableRef> getEliminateVars() {
List<VariableRef> eliminate = new ArrayList<>(); List<VariableRef> eliminate = new ArrayList<>();
VariableRef keepVar = getKeepVar(); VariableRef keepVar = getKeepVar();

View File

@ -23,7 +23,7 @@ public class Pass2AssertBlocks extends Pass2SsaAssertion {
this.graph = graph; this.graph = graph;
} }
private void assertBlock(Label blockLabel) throws AssertionFailed { private void assertBlock(LabelRef blockLabel) throws AssertionFailed {
if (blockLabel == null) { if (blockLabel == null) {
return; return;
} }
@ -53,7 +53,9 @@ public class Pass2AssertBlocks extends Pass2SsaAssertion {
@Override @Override
public Void visitCall(StatementCall callLValue) { public Void visitCall(StatementCall callLValue) {
assertBlock(callLValue.getProcedure().getLabel()); ProcedureRef procedure = callLValue.getProcedure();
LabelRef procLabelRef = procedure.getLabelRef();
assertBlock(procLabelRef);
return super.visitCall(callLValue); return super.visitCall(callLValue);
} }

View File

@ -71,8 +71,8 @@ public class Pass2AssertSymbols extends Pass2SsaAssertion {
private void addSymbol(Value symbol) { private void addSymbol(Value symbol) {
if (symbol instanceof Symbol) { if (symbol instanceof Symbol) {
symbols.add((Symbol) symbol); symbols.add((Symbol) symbol);
} else if(symbol instanceof VariableRef) { } else if(symbol instanceof SymbolRef) {
addSymbol(programScope.getVariable((VariableRef) symbol)); addSymbol(programScope.getSymbol((SymbolRef) symbol));
} else if(symbol instanceof PointerDereferenceIndexed) { } else if(symbol instanceof PointerDereferenceIndexed) {
addSymbol(((PointerDereferenceIndexed) symbol).getPointer()); addSymbol(((PointerDereferenceIndexed) symbol).getPointer());
addSymbol(((PointerDereferenceIndexed) symbol).getIndex()); addSymbol(((PointerDereferenceIndexed) symbol).getIndex());
@ -92,13 +92,17 @@ public class Pass2AssertSymbols extends Pass2SsaAssertion {
@Override @Override
public Void visitProcedureBegin(StatementProcedureBegin statement) { public Void visitProcedureBegin(StatementProcedureBegin statement) {
symbols.add(statement.getProcedure()); ProcedureRef procedureRef = statement.getProcedure();
Procedure procedure = (Procedure) programScope.getSymbol(procedureRef);
symbols.add(procedure);
return super.visitProcedureBegin(statement); return super.visitProcedureBegin(statement);
} }
@Override @Override
public Void visitProcedureEnd(StatementProcedureEnd statement) { public Void visitProcedureEnd(StatementProcedureEnd statement) {
symbols.add(statement.getProcedure()); ProcedureRef procedureRef = statement.getProcedure();
Procedure procedure = (Procedure) programScope.getSymbol(procedureRef);
symbols.add(procedure);
return super.visitProcedureEnd(statement); return super.visitProcedureEnd(statement);
} }

View File

@ -26,7 +26,7 @@ public class Pass2CullEmptyBlocks extends Pass2SsaOptimization {
// Replace all jumps (default/conditional/call) to @removeBlock with a jump to the default successor // Replace all jumps (default/conditional/call) to @removeBlock with a jump to the default successor
final List<ControlFlowBlock> predecessors = getGraph().getPredecessors(removeBlock); final List<ControlFlowBlock> predecessors = getGraph().getPredecessors(removeBlock);
for (ControlFlowBlock predecessor : predecessors) { for (ControlFlowBlock predecessor : predecessors) {
Map<Label, Label> replace = new LinkedHashMap<>(); Map<LabelRef, LabelRef> replace = new LinkedHashMap<>();
replace.put(removeBlock.getLabel(), successor.getLabel()); replace.put(removeBlock.getLabel(), successor.getLabel());
if (removeBlock.getLabel().equals(predecessor.getDefaultSuccessor())) { if (removeBlock.getLabel().equals(predecessor.getDefaultSuccessor())) {
predecessor.setDefaultSuccessor(successor.getLabel()); predecessor.setDefaultSuccessor(successor.getLabel());
@ -63,8 +63,10 @@ public class Pass2CullEmptyBlocks extends Pass2SsaOptimization {
}; };
phiFixVisitor.visitBlock(successor); phiFixVisitor.visitBlock(successor);
getGraph().getAllBlocks().remove(removeBlock); getGraph().getAllBlocks().remove(removeBlock);
removeBlock.getLabel().getScope().remove(removeBlock.getLabel()); LabelRef removeBlockLabelRef = removeBlock.getLabel();
log.append("Culled Empty Block " + removeBlock.getLabel().getTypedName()); Label removeBlockLabel = (Label) getSymbols().getSymbol(removeBlockLabelRef);
removeBlockLabel.getScope().remove(removeBlockLabel);
log.append("Culled Empty Block " + removeBlockLabel.getTypedName());
} }
return remove.size()>0; return remove.size()>0;
} }

View File

@ -189,7 +189,7 @@ public abstract class Pass2SsaOptimization {
* *
* @param replacements Variables that have alias values. * @param replacements Variables that have alias values.
*/ */
public void replaceLabels(final Map<Label, Label> replacements) { public void replaceLabels(final Map<LabelRef, LabelRef> replacements) {
ControlFlowGraphBaseVisitor<Void> visitor = getLabelReplaceVisitor(replacements); ControlFlowGraphBaseVisitor<Void> visitor = getLabelReplaceVisitor(replacements);
visitor.visitGraph(graph); visitor.visitGraph(graph);
} }
@ -199,13 +199,13 @@ public abstract class Pass2SsaOptimization {
* *
* @param replacements Variables that have alias values. * @param replacements Variables that have alias values.
*/ */
public void replaceLabels(ControlFlowBlock block, final Map<Label, Label> replacements) { public void replaceLabels(ControlFlowBlock block, final Map<LabelRef, LabelRef> replacements) {
ControlFlowGraphBaseVisitor<Void> visitor = getLabelReplaceVisitor(replacements); ControlFlowGraphBaseVisitor<Void> visitor = getLabelReplaceVisitor(replacements);
visitor.visitBlock(block); visitor.visitBlock(block);
} }
/** Creates a visitor that can replace labels. */ /** Creates a visitor that can replace labels. */
private ControlFlowGraphBaseVisitor<Void> getLabelReplaceVisitor(final Map<Label, Label> replacements) { private ControlFlowGraphBaseVisitor<Void> getLabelReplaceVisitor(final Map<LabelRef, LabelRef> replacements) {
return new ControlFlowGraphBaseVisitor<Void>() { return new ControlFlowGraphBaseVisitor<Void>() {
@Override @Override
@ -227,7 +227,7 @@ public abstract class Pass2SsaOptimization {
@Override @Override
public Void visitPhi(StatementPhi phi) { public Void visitPhi(StatementPhi phi) {
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) { for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
Label replacement = getReplacement(replacements, previousSymbol.getBlock()); LabelRef replacement = getReplacement(replacements, previousSymbol.getBlock());
if (replacement != null) { if (replacement != null) {
previousSymbol.setBlock(replacement); previousSymbol.setBlock(replacement);
} }
@ -244,8 +244,8 @@ public abstract class Pass2SsaOptimization {
* @param label The label to find a replacement for * @param label The label to find a replacement for
* @return The alias to use. Null if no replacement exists. * @return The alias to use. Null if no replacement exists.
*/ */
private static Label getReplacement(Map<Label, Label> replacements, Label label) { private static LabelRef getReplacement(Map<LabelRef, LabelRef> replacements, LabelRef label) {
Label replacement = replacements.get(label); LabelRef replacement = replacements.get(label);
while (replacements.get(replacement) != null) { while (replacements.get(replacement) != null) {
replacement = replacements.get(replacement); replacement = replacements.get(replacement);
} }

View File

@ -61,8 +61,7 @@ public class TestCompilationOutput extends TestCase {
refLines = loadReferenceLines(fileName, extension); refLines = loadReferenceLines(fileName, extension);
} catch (Exception e) { } catch (Exception e) {
writeOutputFile(fileName, extension, outputString); writeOutputFile(fileName, extension, outputString);
System.out.println("Error loading reference."+e.getMessage()); fail("Error loading reference."+e.getMessage());
return;
} }
// Split output into outLines // Split output into outLines
List<String> outLines = getOutLines(outputString); List<String> outLines = getOutLines(outputString);
@ -71,14 +70,12 @@ public class TestCompilationOutput extends TestCase {
if(refLines.size()>i) { if(refLines.size()>i) {
String refLine = refLines.get(i); String refLine = refLines.get(i);
if(!outLine.equals(refLine)) { if(!outLine.equals(refLine)) {
System.out.println( writeOutputFile(fileName, extension, outputString);
fail(
"Output does not match reference on line "+i+"\n"+ "Output does not match reference on line "+i+"\n"+
"Reference: "+refLine+"\n"+ "Reference: "+refLine+"\n"+
"Output: "+outLine "Output: "+outLine
); );
writeOutputFile(fileName, extension, outputString);
System.out.println();
return;
} }
} }
} }