1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-08-02 09:29:35 +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("_then_");
Label destination = conditionalJump.getDestination();
LabelRef destination = conditionalJump.getDestination();
ControlFlowBlock destinationBlock = graph.getBlock(destination);
String destinationLabel = destination.getFullName();
if (destinationBlock.hasPhiStatements()) {
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();
}

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.*/
public class ControlFlowBlock {
private Label label;
private LabelRef label;
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.statements = new ArrayList<>();
this.defaultSuccessor = null;
this.conditionalSuccessor = null;
}
public Label getLabel() {
public LabelRef getLabel() {
return label;
}
@ -33,27 +33,27 @@ public class ControlFlowBlock {
this.statements.add(statement);
}
public void setDefaultSuccessor(Label defaultSuccessor) {
public void setDefaultSuccessor(LabelRef defaultSuccessor) {
this.defaultSuccessor = defaultSuccessor;
}
public Label getDefaultSuccessor() {
public LabelRef getDefaultSuccessor() {
return defaultSuccessor;
}
public Label getConditionalSuccessor() {
public LabelRef getConditionalSuccessor() {
return conditionalSuccessor;
}
public void setConditionalSuccessor(Label conditionalSuccessor) {
public void setConditionalSuccessor(LabelRef conditionalSuccessor) {
this.conditionalSuccessor = conditionalSuccessor;
}
public Label getCallSuccessor() {
public LabelRef getCallSuccessor() {
return callSuccessor;
}
public void setCallSuccessor(Label callSuccessor) {
public void setCallSuccessor(LabelRef callSuccessor) {
this.callSuccessor = callSuccessor;
}

View File

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

View File

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

View File

@ -98,6 +98,7 @@ public class Label implements Symbol {
}
@Override
@JsonIgnore
public String getAsString() {
return getFullName();
}
@ -106,4 +107,8 @@ public class Label implements Symbol {
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
@JsonIgnore
public String getAsString() {
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;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.HashMap;
@ -77,6 +78,7 @@ public class ProgramScope extends Scope {
}
@Override
@JsonIgnore
public String getAsString() {
return "program";
}

View File

@ -121,6 +121,10 @@ public abstract class Scope implements Symbol {
return symbol;
}
public Symbol getSymbol(SymbolRef symbolRef) {
return getSymbol(symbolRef.getFullName());
}
public Symbol getSymbol(String name) {
int pos = name.indexOf("::");
if (pos >= 0) {
@ -181,6 +185,10 @@ public abstract class Scope implements Symbol {
return (Label) symbols.get(name);
}
public Label getLabel(LabelRef labelRef) {
return (Label) symbols.get(labelRef);
}
public Procedure addProcedure(String name, SymbolType type) {
Symbol symbol = symbols.get(name);
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. */
private LValue lValue;
private String procedureName;
private ProcedureRef procedure;
private List<RValue> parameters;
private Procedure procedure;
private boolean parametersByAssignment;
public StatementCall(LValue lValue, String procedureName, List<RValue> parameters) {
@ -35,11 +35,11 @@ public class StatementCall implements StatementLValue {
return procedureName;
}
public Procedure getProcedure() {
public ProcedureRef getProcedure() {
return procedure;
}
public void setProcedure(Procedure procedure) {
public void setProcedure(ProcedureRef procedure) {
this.procedure = procedure;
}

View File

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

View File

@ -8,17 +8,17 @@ package dk.camelot64.kickc.icl;
*/
public class StatementJump implements Statement {
private Label destination;
private LabelRef destination;
public StatementJump(Label destination) {
public StatementJump(LabelRef destination) {
this.destination = destination;
}
public Label getDestination() {
public LabelRef getDestination() {
return destination;
}
public void setDestination(Label destination) {
public void setDestination(LabelRef destination) {
this.destination = destination;
}
@ -34,5 +34,7 @@ public class StatementJump implements Statement {
@Override
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 {
private Label label;
private LabelRef label;
public StatementLabel(Label label) {
public StatementLabel(LabelRef label) {
this.label = label;
}
public Label getLabel() {
public LabelRef getLabel() {
return label;
}

View File

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

View File

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

View File

@ -3,13 +3,13 @@ package dk.camelot64.kickc.icl;
/** Procedure declaration in SSA */
public class StatementProcedureEnd implements Statement {
private Procedure procedure;
private ProcedureRef procedure;
public StatementProcedureEnd(Procedure procedure) {
public StatementProcedureEnd(ProcedureRef procedure) {
this.procedure = procedure;
}
public Procedure getProcedure() {
public ProcedureRef getProcedure() {
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
@JsonIgnore
public String getAsString() {
return getTypedName();
}

View File

@ -1,59 +1,14 @@
package dk.camelot64.kickc.icl;
/** A reference to a variable from the symbol table */
public class VariableRef implements RValue, LValue {
/** The full name of the variable. Allowing lookup in the symbol table. */
private String fullName;
public class VariableRef extends SymbolRef implements RValue, LValue {
public VariableRef(String fullName) {
this.fullName = fullName;
super(fullName);
}
public VariableRef(Variable variable) {
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 END_BLOCK_NAME = "@END";
private Scope scope;
private Map<Symbol, ControlFlowBlock> blocks;
private Map<SymbolRef, ControlFlowBlock> blocks;
private ControlFlowBlock firstBlock;
public Pass1GenerateControlFlowGraph(Scope scope) {
@ -21,10 +21,10 @@ public class Pass1GenerateControlFlowGraph {
}
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<>();
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()) {
ControlFlowBlock currentBlock = blockStack.peek();
if(statement instanceof StatementLabel) {
@ -37,14 +37,14 @@ public class Pass1GenerateControlFlowGraph {
StatementJump statementJump = (StatementJump) statement;
ControlFlowBlock jmpBlock = getOrCreateBlock(statementJump.getDestination());
currentBlock.setDefaultSuccessor(jmpBlock.getLabel());
ControlFlowBlock nextBlock = getOrCreateBlock(scope.addLabelIntermediate());
ControlFlowBlock nextBlock = getOrCreateBlock(scope.addLabelIntermediate().getRef());
blockStack.pop();
blockStack.push(nextBlock);
} else if(statement instanceof StatementConditionalJump) {
currentBlock.addStatement(statement);
StatementConditionalJump statementConditionalJump = (StatementConditionalJump) statement;
ControlFlowBlock jmpBlock = getOrCreateBlock(statementConditionalJump.getDestination());
ControlFlowBlock nextBlock = getOrCreateBlock(scope.addLabelIntermediate());
ControlFlowBlock nextBlock = getOrCreateBlock(scope.addLabelIntermediate().getRef());
currentBlock.setDefaultSuccessor(nextBlock.getLabel());
currentBlock.setConditionalSuccessor(jmpBlock.getLabel());
blockStack.pop();
@ -53,13 +53,14 @@ public class Pass1GenerateControlFlowGraph {
// Procedure strategy implemented is currently variable-based transfer of parameters/return values
StatementProcedureBegin procedureBegin = (StatementProcedureBegin) statement;
procedureBegin.setStrategy(StatementProcedureBegin.Strategy.PASS_BY_REGISTER);
Label procedureLabel = procedureBegin.getProcedure().getLabel();
ControlFlowBlock procBlock = getOrCreateBlock(procedureLabel);
ProcedureRef procedureRef = procedureBegin.getProcedure();
LabelRef procedureLabelRef = procedureRef.getLabelRef();
ControlFlowBlock procBlock = getOrCreateBlock(procedureLabelRef);
blockStack.push(procBlock);
} else if(statement instanceof StatementProcedureEnd) {
// Procedure strategy implemented is currently variable-based transfer of parameters/return values
currentBlock.setDefaultSuccessor(new Label("@RETURN", scope, false));
ControlFlowBlock nextBlock = getOrCreateBlock(scope.addLabelIntermediate());
currentBlock.setDefaultSuccessor(new Label("@RETURN", scope, false).getRef());
ControlFlowBlock nextBlock = getOrCreateBlock(scope.addLabelIntermediate().getRef());
blockStack.pop();
ControlFlowBlock prevBlock = blockStack.pop();
prevBlock.setDefaultSuccessor(nextBlock.getLabel());
@ -77,7 +78,7 @@ public class Pass1GenerateControlFlowGraph {
return new ControlFlowGraph(blocks, firstBlock);
}
private ControlFlowBlock getOrCreateBlock(Label label) {
private ControlFlowBlock getOrCreateBlock(LabelRef label) {
ControlFlowBlock block = blocks.get(label);
if(block==null) {
block = new ControlFlowBlock(label);

View File

@ -170,8 +170,8 @@ public class Pass1GenerateSingleStaticAssignmentForm {
* false if new phis were added, meaning another iteration is needed.
*/
private boolean completePhiFunctions() {
Map<Label, Map<VariableUnversioned, VariableVersion>> newPhis = new LinkedHashMap<>();
Map<Label, Map<VariableUnversioned, VariableVersion>> symbolMap = buildSymbolMap();
Map<LabelRef, Map<VariableUnversioned, VariableVersion>> newPhis = new LinkedHashMap<>();
Map<LabelRef, Map<VariableUnversioned, VariableVersion>> symbolMap = buildSymbolMap();
for (ControlFlowBlock block : this.controlFlowGraph.getAllBlocks()) {
for (Statement statement : block.getStatements()) {
if (statement instanceof StatementPhi) {
@ -181,7 +181,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
VariableVersion versioned = (VariableVersion) symbols.getVariable(phiLValVarRef);
VariableUnversioned unversioned = versioned.getVersionOf();
for (ControlFlowBlock predecessor : controlFlowGraph.getPredecessors(block)) {
Label predecessorLabel = predecessor.getLabel();
LabelRef predecessorLabel = predecessor.getLabel();
Map<VariableUnversioned, VariableVersion> predecessorMap = symbolMap.get(predecessorLabel);
VariableVersion previousSymbol = null;
if (predecessorMap != null) {
@ -223,8 +223,8 @@ public class Pass1GenerateSingleStaticAssignmentForm {
* 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.
*/
private Map<Label, Map<VariableUnversioned, VariableVersion>> buildSymbolMap() {
Map<Label, Map<VariableUnversioned, VariableVersion>> symbolMap = new LinkedHashMap<>();
private Map<LabelRef, Map<VariableUnversioned, VariableVersion>> buildSymbolMap() {
Map<LabelRef, Map<VariableUnversioned, VariableVersion>> symbolMap = new LinkedHashMap<>();
for (ControlFlowBlock block : this.controlFlowGraph.getAllBlocks()) {
for (Statement statement : block.getStatements()) {
if (statement instanceof StatementLValue) {
@ -234,7 +234,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
Variable lValueVar = symbols.getVariable((VariableRef) lValue);
if (lValueVar instanceof VariableVersion) {
VariableVersion versioned = (VariableVersion) lValueVar;
Label label = block.getLabel();
LabelRef label = block.getLabel();
VariableUnversioned unversioned = versioned.getVersionOf();
Map<VariableUnversioned, VariableVersion> blockMap = symbolMap.get(label);
if (blockMap == null) {

View File

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

View File

@ -24,7 +24,8 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
public StatementCall visitCall(StatementCall origCall) {
// Procedure strategy implemented is currently variable-based transfer of parameters/return values
// Generate parameter passing assignments
Procedure procedure = origCall.getProcedure();
ProcedureRef procedureRef = origCall.getProcedure();
Procedure procedure = (Procedure) scope.getSymbol(procedureRef);
List<Variable> parameterDecls = procedure.getParameters();
List<RValue> parameterValues = origCall.getParameters();
for (int i = 0; i < parameterDecls.size(); i++) {
@ -35,13 +36,15 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
String procedureName = origCall.getProcedureName();
Variable procReturnVar = procedure.getVariable("return");
VariableRef procReturnVarRef = null;
if(procReturnVar!=null) {new VariableRef(procReturnVar); }
if (procReturnVar != null) {
procReturnVarRef = new VariableRef(procReturnVar);
}
StatementCall copyCall = new StatementCall(procReturnVarRef, procedureName, null);
copyCall.setParametersByAssignment(true);
copyCall.setProcedure(procedure);
copyCall.setProcedure(procedureRef);
addStatementToCurrentBlock(copyCall);
getCurrentBlock().setCallSuccessor(procedure.getLabel());
splitCurrentBlock(scope.addLabelIntermediate());
getCurrentBlock().setCallSuccessor(procedure.getLabel().getRef());
splitCurrentBlock(scope.addLabelIntermediate().getRef());
if(!SymbolTypeBasic.VOID.equals(procedure.getReturnType())) {
addStatementToCurrentBlock(new StatementAssignment(origCall.getlValue(), procReturnVarRef));
} 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 */
public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor {
private Scope scope;
private ProgramScope scope;
private ControlFlowGraph graph;
public Pass1ProcedureCallsReturnValue(Scope scope, ControlFlowGraph graph) {
public Pass1ProcedureCallsReturnValue(ProgramScope scope, ControlFlowGraph graph) {
this.scope = scope;
this.graph = graph;
}
@ -22,18 +22,19 @@ public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor
public StatementCall visitCall(StatementCall origCall) {
// Procedure strategy implemented is currently variable-based transfer of parameters/return values
// Generate return value assignment
Procedure procedure = origCall.getProcedure();
ProcedureRef procedureRef = origCall.getProcedure();
Procedure procedure = (Procedure) scope.getSymbol(procedureRef);
String procedureName = origCall.getProcedureName();
StatementCall copyCall = new StatementCall(null, procedureName, null);
copyCall.setParametersByAssignment(true);
copyCall.setProcedure(procedure);
copyCall.setProcedure(procedureRef);
addStatementToCurrentBlock(copyCall);
getCurrentBlock().setCallSuccessor(procedure.getLabel());
getCurrentBlock().setCallSuccessor(procedure.getLabel().getRef());
if(!SymbolTypeBasic.VOID.equals(procedure.getReturnType())) {
// Find return variable final version
Label returnBlockLabel = procedure.getLabel("@return");
ControlFlowBlock returnBlock = graph.getBlock(returnBlockLabel);
ControlFlowBlock returnBlock = graph.getBlock(returnBlockLabel.getRef());
VariableRef returnVarFinal = null;
for (Statement statement : returnBlock.getStatements()) {
if (statement instanceof StatementReturn) {

View File

@ -22,7 +22,9 @@ public class Pass1TypeInference {
for (Statement statement : sequence.getStatements()) {
if(statement instanceof StatementProcedureBegin) {
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) {
scopes.pop();
} else if (statement instanceof StatementAssignment) {
@ -54,7 +56,7 @@ public class Pass1TypeInference {
if(lValue instanceof VariableRef) {
String procedureName = call.getProcedureName();
Procedure procedure = scopes.peek().getProcedure(procedureName);
call.setProcedure(procedure);
call.setProcedure(procedure.getRef());
if(procedure.getParameters().size()!=call.getParameters().size()) {
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) {
keep = var;
} else {
if (isVersion(var)) {
if (isVersion(keep)) {
if (getScopeDepth(var) < getScopeDepth(keep)) {
if (var.isVersion()) {
if (keep.isVersion()) {
if (var.getScopeDepth() < keep.getScopeDepth()) {
keep = var;
}
} else {
@ -193,19 +193,6 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
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() {
List<VariableRef> eliminate = new ArrayList<>();
VariableRef keepVar = getKeepVar();

View File

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

View File

@ -71,8 +71,8 @@ public class Pass2AssertSymbols extends Pass2SsaAssertion {
private void addSymbol(Value symbol) {
if (symbol instanceof Symbol) {
symbols.add((Symbol) symbol);
} else if(symbol instanceof VariableRef) {
addSymbol(programScope.getVariable((VariableRef) symbol));
} else if(symbol instanceof SymbolRef) {
addSymbol(programScope.getSymbol((SymbolRef) symbol));
} else if(symbol instanceof PointerDereferenceIndexed) {
addSymbol(((PointerDereferenceIndexed) symbol).getPointer());
addSymbol(((PointerDereferenceIndexed) symbol).getIndex());
@ -92,13 +92,17 @@ public class Pass2AssertSymbols extends Pass2SsaAssertion {
@Override
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);
}
@Override
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);
}

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
final List<ControlFlowBlock> predecessors = getGraph().getPredecessors(removeBlock);
for (ControlFlowBlock predecessor : predecessors) {
Map<Label, Label> replace = new LinkedHashMap<>();
Map<LabelRef, LabelRef> replace = new LinkedHashMap<>();
replace.put(removeBlock.getLabel(), successor.getLabel());
if (removeBlock.getLabel().equals(predecessor.getDefaultSuccessor())) {
predecessor.setDefaultSuccessor(successor.getLabel());
@ -63,8 +63,10 @@ public class Pass2CullEmptyBlocks extends Pass2SsaOptimization {
};
phiFixVisitor.visitBlock(successor);
getGraph().getAllBlocks().remove(removeBlock);
removeBlock.getLabel().getScope().remove(removeBlock.getLabel());
log.append("Culled Empty Block " + removeBlock.getLabel().getTypedName());
LabelRef removeBlockLabelRef = removeBlock.getLabel();
Label removeBlockLabel = (Label) getSymbols().getSymbol(removeBlockLabelRef);
removeBlockLabel.getScope().remove(removeBlockLabel);
log.append("Culled Empty Block " + removeBlockLabel.getTypedName());
}
return remove.size()>0;
}

View File

@ -189,7 +189,7 @@ public abstract class Pass2SsaOptimization {
*
* @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);
visitor.visitGraph(graph);
}
@ -199,13 +199,13 @@ public abstract class Pass2SsaOptimization {
*
* @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);
visitor.visitBlock(block);
}
/** 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>() {
@Override
@ -227,7 +227,7 @@ public abstract class Pass2SsaOptimization {
@Override
public Void visitPhi(StatementPhi phi) {
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
Label replacement = getReplacement(replacements, previousSymbol.getBlock());
LabelRef replacement = getReplacement(replacements, previousSymbol.getBlock());
if (replacement != null) {
previousSymbol.setBlock(replacement);
}
@ -244,8 +244,8 @@ public abstract class Pass2SsaOptimization {
* @param label The label to find a replacement for
* @return The alias to use. Null if no replacement exists.
*/
private static Label getReplacement(Map<Label, Label> replacements, Label label) {
Label replacement = replacements.get(label);
private static LabelRef getReplacement(Map<LabelRef, LabelRef> replacements, LabelRef label) {
LabelRef replacement = replacements.get(label);
while (replacements.get(replacement) != null) {
replacement = replacements.get(replacement);
}

View File

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