1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-03 12:07:26 +00:00

Added proc/endproc statements

This commit is contained in:
jespergravgaard 2017-06-05 16:17:08 +02:00
parent 03ee43c3b7
commit 40d44da2fc
25 changed files with 105 additions and 83 deletions

View File

@ -20,7 +20,7 @@ public class AsmFragment {
/**
* The symbol table.
*/
private SymbolTable symbols;
private Scope symbols;
/**
* Binding of named values in the fragment to values (constants, variables, ...) .
@ -32,26 +32,26 @@ public class AsmFragment {
*/
private String signature;
public AsmFragment(StatementConditionalJump conditionalJump, ControlFlowBlock block, SymbolTable symbols, ControlFlowGraph graph) {
public AsmFragment(StatementConditionalJump conditionalJump, ControlFlowBlock block, Scope symbols, ControlFlowGraph graph) {
this.bindings = new HashMap<>();
this.symbols = symbols;
String conditionalJumpSignature = conditionalJumpSignature(conditionalJump, block, graph);
setSignature(conditionalJumpSignature);
}
public AsmFragment(StatementAssignment assignment, SymbolTable symbols) {
public AsmFragment(StatementAssignment assignment, Scope symbols) {
this.bindings = new HashMap<>();
this.symbols = symbols;
setSignature(assignmentSignature(assignment.getLValue(), assignment.getRValue1(), assignment.getOperator(), assignment.getRValue2()));
}
public AsmFragment(LValue lValue, RValue rValue, SymbolTable symbols) {
public AsmFragment(LValue lValue, RValue rValue, Scope symbols) {
this.bindings = new HashMap<>();
this.symbols = symbols;
setSignature(assignmentSignature(lValue, null, null, rValue));
}
public AsmFragment(StatementAssignment assignment, StatementAssignment assignmentAlu, SymbolTable symbols) {
public AsmFragment(StatementAssignment assignment, StatementAssignment assignmentAlu, Scope symbols) {
this.bindings = new HashMap<>();
this.symbols = symbols;
setSignature(assignmentWithAluSignature(assignment, assignmentAlu));

View File

@ -7,11 +7,11 @@ public class Label implements Symbol {
private String name;
/** The name of the containing scope */
private SymbolTable scope;
private Scope scope;
private boolean intermediate;
public Label(String name, SymbolTable scope, boolean intermediate) {
public Label(String name, Scope scope, boolean intermediate) {
this.name = name;
this.scope = scope;
this.intermediate = intermediate;
@ -22,13 +22,13 @@ public class Label implements Symbol {
}
@Override
public SymbolTable getScope() {
public Scope getScope() {
return scope;
}
@Override
public String getFullName() {
return SymbolTable.getFullName(this);
return Scope.getFullName(this);
}
public boolean isIntermediate() {

View File

@ -8,19 +8,19 @@ public class Pass1GenerateControlFlowGraph {
public static final String BEGIN_BLOCK_NAME = "@BEGIN";
public static final String END_BLOCK_NAME = "@END";
private SymbolTable symbolTable;
private Scope scope;
private Map<Symbol, ControlFlowBlock> blocks;
private ControlFlowBlock firstBlock;
public Pass1GenerateControlFlowGraph(SymbolTable symbolTable) {
this.symbolTable = symbolTable;
public Pass1GenerateControlFlowGraph(Scope scope) {
this.scope = scope;
this.blocks = new LinkedHashMap<>();
}
public ControlFlowGraph generate(StatementSequence sequence) {
this.firstBlock = getOrCreateBlock(symbolTable.addLabel(BEGIN_BLOCK_NAME));
this.firstBlock = getOrCreateBlock(scope.addLabel(BEGIN_BLOCK_NAME));
ControlFlowBlock currentBlock = this.firstBlock;
sequence.addStatement(new StatementLabel(symbolTable.addLabel(END_BLOCK_NAME)));
sequence.addStatement(new StatementLabel(scope.addLabel(END_BLOCK_NAME)));
for (Statement statement : sequence.getStatements()) {
if(statement instanceof StatementLabel) {
StatementLabel statementLabel = (StatementLabel) statement;
@ -33,13 +33,13 @@ public class Pass1GenerateControlFlowGraph {
ControlFlowBlock jmpBlock = getOrCreateBlock(statementJump.getDestination());
currentBlock.setDefaultSuccessor(jmpBlock);
jmpBlock.addPredecessor(currentBlock);
ControlFlowBlock nextBlock = getOrCreateBlock(symbolTable.addLabelIntermediate());
ControlFlowBlock nextBlock = getOrCreateBlock(scope.addLabelIntermediate());
currentBlock = nextBlock;
} else if(statement instanceof StatementConditionalJump) {
currentBlock.addStatement(statement);
StatementConditionalJump statementConditionalJump = (StatementConditionalJump) statement;
ControlFlowBlock jmpBlock = getOrCreateBlock(statementConditionalJump.getDestination());
ControlFlowBlock nextBlock = getOrCreateBlock(symbolTable.addLabelIntermediate());
ControlFlowBlock nextBlock = getOrCreateBlock(scope.addLabelIntermediate());
currentBlock.setDefaultSuccessor(nextBlock);
currentBlock.setConditionalSuccessor(jmpBlock);
nextBlock.addPredecessor(currentBlock);

View File

@ -10,10 +10,10 @@ import java.util.Map;
*/
public class Pass1GenerateSingleStaticAssignmentForm {
private SymbolTable symbols;
private Scope symbols;
private ControlFlowGraph controlFlowGraph;
public Pass1GenerateSingleStaticAssignmentForm(SymbolTable symbols, ControlFlowGraph controlFlowGraph) {
public Pass1GenerateSingleStaticAssignmentForm(Scope symbols, ControlFlowGraph controlFlowGraph) {
this.symbols = symbols;
this.controlFlowGraph = controlFlowGraph;
}

View File

@ -13,22 +13,22 @@ import java.util.Stack;
*/
public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
private SymbolTable programSymbols;
private Stack<SymbolTable> symbolsStack;
private Scope programSymbols;
private Stack<Scope> symbolsStack;
private StatementSequence sequence;
public Pass1GenerateStatementSequence() {
this.programSymbols = new SymbolTable();
this.programSymbols = new Scope();
this.symbolsStack = new Stack<>();
symbolsStack.push(programSymbols);
this.sequence = new StatementSequence();
}
public SymbolTable getProgramSymbols() {
public Scope getProgramSymbols() {
return programSymbols;
}
private SymbolTable getCurrentSymbols() {
private Scope getCurrentSymbols() {
return symbolsStack.peek();
}
@ -133,9 +133,10 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
symbolsStack.push(procedure);
List<Variable> parameterList = (List<Variable>) this.visit(ctx.parameterListDecl());
procedure.setParameters(parameterList);
sequence.addStatement(new StatementProcedure(procedure));
sequence.addStatement(new StatementProcedureBegin(procedure));
this.visit(ctx.stmtSeq());
symbolsStack.pop();
sequence.addStatement(new StatementProcedureEnd(procedure));
return null;
}

View File

@ -5,8 +5,8 @@ import java.util.*;
/** Compiler Pass eliminating alias assignments */
public class Pass2AliasElimination extends Pass2SsaOptimization {
public Pass2AliasElimination(ControlFlowGraph graph, SymbolTable symbolTable) {
super(graph, symbolTable);
public Pass2AliasElimination(ControlFlowGraph graph, Scope scope) {
super(graph, scope);
}

View File

@ -11,8 +11,8 @@ public class Pass2ConditionalJumpSimplification extends Pass2SsaOptimization {
private Map<Variable, List<Statement>> allUsages;
public Pass2ConditionalJumpSimplification(ControlFlowGraph graph, SymbolTable symbolTable) {
super(graph, symbolTable);
public Pass2ConditionalJumpSimplification(ControlFlowGraph graph, Scope scope) {
super(graph, scope);
}
/**

View File

@ -5,8 +5,8 @@ package dk.camelot64.kickc.icl;
*/
public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
public Pass2ConstantAdditionElimination(ControlFlowGraph graph, SymbolTable symbolTable) {
super(graph, symbolTable);
public Pass2ConstantAdditionElimination(ControlFlowGraph graph, Scope scope) {
super(graph, scope);
}
/**

View File

@ -6,8 +6,8 @@ import java.util.Map;
/** Compiler Pass propagating constants in expressions eliminating constant variables */
public class Pass2ConstantPropagation extends Pass2SsaOptimization {
public Pass2ConstantPropagation(ControlFlowGraph graph, SymbolTable symbolTable) {
super(graph, symbolTable);
public Pass2ConstantPropagation(ControlFlowGraph graph, Scope scope) {
super(graph, scope);
}
/**

View File

@ -5,8 +5,8 @@ import java.util.*;
/** Pass that culls empty control flow blocks from the program */
public class Pass2CullEmptyBlocks extends Pass2SsaOptimization {
public Pass2CullEmptyBlocks(ControlFlowGraph graph, SymbolTable symbolTable) {
super(graph, symbolTable);
public Pass2CullEmptyBlocks(ControlFlowGraph graph, Scope scope) {
super(graph, scope);
}
@Override

View File

@ -6,8 +6,8 @@ import java.util.Map;
/** Compiler Pass eliminating redundant phi functions */
public class Pass2RedundantPhiElimination extends Pass2SsaOptimization {
public Pass2RedundantPhiElimination(ControlFlowGraph graph, SymbolTable symbolTable) {
super(graph, symbolTable);
public Pass2RedundantPhiElimination(ControlFlowGraph graph, Scope scope) {
super(graph, scope);
}
/**

View File

@ -5,8 +5,8 @@ import java.util.Iterator;
/** Compiler Pass eliminating phi self assignments */
public class Pass2SelfPhiElimination extends Pass2SsaOptimization {
public Pass2SelfPhiElimination(ControlFlowGraph graph, SymbolTable symbolTable) {
super(graph, symbolTable);
public Pass2SelfPhiElimination(ControlFlowGraph graph, Scope scope) {
super(graph, scope);
}
/**

View File

@ -9,19 +9,19 @@ import java.util.*;
public abstract class Pass2SsaOptimization {
private ControlFlowGraph graph;
private SymbolTable symbolTable;
private Scope scope;
public Pass2SsaOptimization(ControlFlowGraph graph, SymbolTable symbolTable) {
public Pass2SsaOptimization(ControlFlowGraph graph, Scope scope) {
this.graph = graph;
this.symbolTable = symbolTable;
this.scope = scope;
}
public ControlFlowGraph getGraph() {
return graph;
}
public SymbolTable getSymbols() {
return symbolTable;
public Scope getSymbols() {
return scope;
}
/**
@ -226,7 +226,7 @@ public abstract class Pass2SsaOptimization {
*/
public void deleteSymbols(Collection<? extends LValue> variables) {
for (LValue variable : variables) {
symbolTable.remove((Symbol) variable);
scope.remove((Symbol) variable);
}
}

View File

@ -10,9 +10,9 @@ import java.util.Iterator;
public class Pass3CodeGeneration {
private ControlFlowGraph graph;
private SymbolTable symbols;
private Scope symbols;
public Pass3CodeGeneration(ControlFlowGraph graph, SymbolTable symbols) {
public Pass3CodeGeneration(ControlFlowGraph graph, Scope symbols) {
this.graph = graph;
this.symbols = symbols;
}

View File

@ -4,9 +4,9 @@ package dk.camelot64.kickc.icl;
public class Pass3RegisterAllocation {
private ControlFlowGraph graph;
private SymbolTable symbols;
private Scope symbols;
public Pass3RegisterAllocation(ControlFlowGraph graph, SymbolTable symbols) {
public Pass3RegisterAllocation(ControlFlowGraph graph, Scope symbols) {
this.graph = graph;
this.symbols = symbols;
}

View File

@ -5,7 +5,7 @@ package dk.camelot64.kickc.icl;
*/
public class PassTypeInference {
public void inferTypes(StatementSequence sequence, SymbolTable symbols) {
public void inferTypes(StatementSequence sequence, Scope symbols) {
for (Statement statement : sequence.getStatements()) {
if (statement instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) statement;

View File

@ -3,12 +3,12 @@ package dk.camelot64.kickc.icl;
import java.util.List;
/** Symbol describing a procedure/function */
public class Procedure extends SymbolTable {
public class Procedure extends Scope {
private final SymbolType returnType;
private List<Variable> parameters;
public Procedure(String name, SymbolType returnType, SymbolTable parentScope) {
public Procedure(String name, SymbolType returnType, Scope parentScope) {
super(name, new SymbolTypeProcedure(returnType), parentScope);
this.returnType = returnType;
}

View File

@ -5,7 +5,7 @@ import java.util.*;
/**
* Manages symbols (variables, labels)
*/
public class SymbolTable implements Symbol {
public class Scope implements Symbol {
private String name;
private SymbolType type;
@ -13,16 +13,16 @@ public class SymbolTable implements Symbol {
private int intermediateVarCount = 0;
private int intermediateLabelCount = 1;
private RegisterAllocation allocation;
private SymbolTable parentScope;
private Scope parentScope;
public SymbolTable(String name, SymbolType type, SymbolTable parentScope) {
public Scope(String name, SymbolType type, Scope parentScope) {
this.name = name;
this.type = type;
this.parentScope = parentScope;
this.symbols = new LinkedHashMap<>();
}
public SymbolTable() {
public Scope() {
this.name = "";
this.type = new SymbolTypeProgram();
this.parentScope = null;
@ -51,7 +51,7 @@ public class SymbolTable implements Symbol {
@Override
public SymbolTable getScope() {
public Scope getScope() {
return parentScope;
}
@ -162,8 +162,8 @@ public class SymbolTable implements Symbol {
Collections.sort(sortedNames);
for (String name : sortedNames) {
Symbol symbol = symbols.get(name);
if (symbol instanceof SymbolTable) {
res.append(((SymbolTable) symbol).getSymbolTableContents());
if (symbol instanceof Scope) {
res.append(((Scope) symbol).getSymbolTableContents());
} else {
res.append(symbol.toString());
}

View File

@ -1,11 +1,11 @@
package dk.camelot64.kickc.icl;
/** Procedure declaration in SSA */
public class StatementProcedure implements Statement {
public class StatementProcedureBegin implements Statement {
private Procedure procedure;
public StatementProcedure(Procedure procedure) {
public StatementProcedureBegin(Procedure procedure) {
this.procedure = procedure;
}
@ -15,7 +15,7 @@ public class StatementProcedure implements Statement {
@Override
public String toString() {
return "proc "+procedure.toString()+":";
return "proc "+procedure.toString();
}
}

View File

@ -0,0 +1,21 @@
package dk.camelot64.kickc.icl;
/** Procedure declaration in SSA */
public class StatementProcedureEnd implements Statement {
private Procedure procedure;
public StatementProcedureEnd(Procedure procedure) {
this.procedure = procedure;
}
public Procedure getProcedure() {
return procedure;
}
@Override
public String toString() {
return "endproc // "+procedure.getLocalName()+"()";
}
}

View File

@ -11,7 +11,7 @@ public interface Symbol extends Value {
SymbolType getType();
SymbolTable getScope();
Scope getScope();
}

View File

@ -13,7 +13,7 @@ public abstract class Variable implements Symbol, RValue, LValue {
/**
* Scope
*/
private SymbolTable scope;
private Scope scope;
/**
* The type of the symbol. VAR means tha type is unknown, and has not been inferred yet.
@ -25,7 +25,7 @@ public abstract class Variable implements Symbol, RValue, LValue {
*/
private boolean inferredType;
public Variable(String name, SymbolTable scope, SymbolType type) {
public Variable(String name, Scope scope, SymbolType type) {
this.name = name;
this.scope = scope;
this.type = type;
@ -38,7 +38,7 @@ public abstract class Variable implements Symbol, RValue, LValue {
@Override
public String getFullName() {
return SymbolTable.getFullName(this);
return Scope.getFullName(this);
}
@Override
@ -90,7 +90,7 @@ public abstract class Variable implements Symbol, RValue, LValue {
return getTypedName();
}
public SymbolTable getScope() {
public Scope getScope() {
return scope;
}
}

View File

@ -5,7 +5,7 @@ package dk.camelot64.kickc.icl;
*/
public class VariableIntermediate extends Variable {
public VariableIntermediate(String name, SymbolTable scope, SymbolType type) {
public VariableIntermediate(String name, Scope scope, SymbolType type) {
super(name, scope, type);
}

View File

@ -10,7 +10,7 @@ public class VariableUnversioned extends Variable {
*/
private Integer nextVersionNumber;
public VariableUnversioned(String name, SymbolTable scope, SymbolType type) {
public VariableUnversioned(String name, Scope scope, SymbolType type) {
super(name, scope, type);
this.nextVersionNumber = 0;
}

View File

@ -29,29 +29,29 @@ public class Main {
Pass1GenerateStatementSequence pass1GenerateStatementSequence = new Pass1GenerateStatementSequence();
pass1GenerateStatementSequence.generate(file);
StatementSequence statementSequence = pass1GenerateStatementSequence.getSequence();
SymbolTable symbolTable = pass1GenerateStatementSequence.getProgramSymbols();
new PassTypeInference().inferTypes(statementSequence, symbolTable);
Scope scope = pass1GenerateStatementSequence.getProgramSymbols();
new PassTypeInference().inferTypes(statementSequence, scope);
System.out.println("PROGRAM");
System.out.println(statementSequence.toString());
System.out.println("SYMBOLS");
System.out.println(symbolTable.getSymbolTableContents());
System.out.println(scope.getSymbolTableContents());
Pass1GenerateControlFlowGraph pass1GenerateControlFlowGraph = new Pass1GenerateControlFlowGraph(symbolTable);
Pass1GenerateControlFlowGraph pass1GenerateControlFlowGraph = new Pass1GenerateControlFlowGraph(scope);
ControlFlowGraph controlFlowGraph = pass1GenerateControlFlowGraph.generate(statementSequence);
Pass1GenerateSingleStaticAssignmentForm pass1GenerateSingleStaticAssignmentForm =
new Pass1GenerateSingleStaticAssignmentForm(symbolTable, controlFlowGraph);
new Pass1GenerateSingleStaticAssignmentForm(scope, controlFlowGraph);
pass1GenerateSingleStaticAssignmentForm.generate();
List<Pass2SsaOptimization> optimizations = new ArrayList<>();
optimizations.add(new Pass2CullEmptyBlocks(controlFlowGraph, symbolTable));
optimizations.add(new Pass2ConstantPropagation(controlFlowGraph, symbolTable));
optimizations.add(new Pass2ConstantAdditionElimination(controlFlowGraph, symbolTable));
optimizations.add(new Pass2AliasElimination(controlFlowGraph, symbolTable));
optimizations.add(new Pass2RedundantPhiElimination(controlFlowGraph, symbolTable));
optimizations.add(new Pass2SelfPhiElimination(controlFlowGraph, symbolTable));
optimizations.add(new Pass2ConditionalJumpSimplification(controlFlowGraph, symbolTable));
optimizations.add(new Pass2CullEmptyBlocks(controlFlowGraph, scope));
optimizations.add(new Pass2ConstantPropagation(controlFlowGraph, scope));
optimizations.add(new Pass2ConstantAdditionElimination(controlFlowGraph, scope));
optimizations.add(new Pass2AliasElimination(controlFlowGraph, scope));
optimizations.add(new Pass2RedundantPhiElimination(controlFlowGraph, scope));
optimizations.add(new Pass2SelfPhiElimination(controlFlowGraph, scope));
optimizations.add(new Pass2ConditionalJumpSimplification(controlFlowGraph, scope));
System.out.println("INITIAL CONTROL FLOW GRAPH");
System.out.println(controlFlowGraph.toString());
@ -70,9 +70,9 @@ public class Main {
}
}
Pass3RegisterAllocation pass3RegisterAllocation = new Pass3RegisterAllocation(controlFlowGraph, symbolTable);
Pass3RegisterAllocation pass3RegisterAllocation = new Pass3RegisterAllocation(controlFlowGraph, scope);
pass3RegisterAllocation.allocate();
Pass3CodeGeneration pass3CodeGeneration = new Pass3CodeGeneration(controlFlowGraph, symbolTable);
Pass3CodeGeneration pass3CodeGeneration = new Pass3CodeGeneration(controlFlowGraph, scope);
AsmProgram asmProgram = pass3CodeGeneration.generate();
System.out.println("INITIAL ASM");
@ -96,7 +96,7 @@ public class Main {
}
System.out.println("SYMBOLS");
System.out.println(symbolTable.toString());
System.out.println(scope.toString());
System.out.println("CONTROL FLOW GRAPH");
System.out.println(controlFlowGraph.toString());
System.out.println("ASSEMBLER");