mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-23 13:31:12 +00:00
Replaced all program labels with labelrefs ans procedures with procedurerefs.
This commit is contained in:
parent
e6d09187e3
commit
de88808c5f
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
14
src/dk/camelot64/kickc/icl/LabelRef.java
Normal file
14
src/dk/camelot64/kickc/icl/LabelRef.java
Normal 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());
|
||||
}
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
13
src/dk/camelot64/kickc/icl/ProcedureRef.java
Normal file
13
src/dk/camelot64/kickc/icl/ProcedureRef.java
Normal 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());
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
93
src/dk/camelot64/kickc/icl/SymbolRef.java
Normal file
93
src/dk/camelot64/kickc/icl/SymbolRef.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -129,6 +129,7 @@ public abstract class Variable implements Symbol {
|
||||
}
|
||||
|
||||
@Override
|
||||
@JsonIgnore
|
||||
public String getAsString() {
|
||||
return getTypedName();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user