1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-08-09 04:25:12 +00:00

Now supporting fibonacci array generation

This commit is contained in:
jespergravgaard
2017-05-28 12:46:14 +02:00
parent 6f56b1bcfa
commit b3dfb503f5
26 changed files with 271 additions and 84 deletions

View File

@@ -101,6 +101,8 @@ public class AsmFragment {
private static String getOperatorFragmentName(Operator operator) { private static String getOperatorFragmentName(Operator operator) {
String op = operator.getOperator(); String op = operator.getOperator();
switch (op) { switch (op) {
case "*":
return "_star_";
case "+": case "+":
return "_plus_"; return "_plus_";
case "-": case "-":
@@ -198,8 +200,8 @@ public class AsmFragment {
bindings.put(name, value); bindings.put(name, value);
return name; return name;
} }
} else if (value instanceof PointerDereference) { } else if (value instanceof PointerDereferenceVariable) {
PointerDereference deref = (PointerDereference) value; PointerDereferenceVariable deref = (PointerDereferenceVariable) value;
Variable pointer = deref.getPointer(); Variable pointer = deref.getPointer();
RegisterAllocation.Register register = symbols.getRegister(pointer); RegisterAllocation.Register register = symbols.getRegister(pointer);
if (RegisterAllocation.RegisterType.ZP_PTR_BYTE.equals(register.getType())) { if (RegisterAllocation.RegisterType.ZP_PTR_BYTE.equals(register.getType())) {
@@ -207,13 +209,21 @@ public class AsmFragment {
bindings.put(name, value); bindings.put(name, value);
return name; return name;
} }
} else if (value instanceof PointerDereferenceConstant) {
PointerDereferenceConstant deref = (PointerDereferenceConstant) value;
Constant pointer = deref.getPointer();
if(pointer instanceof ConstantInteger) {
String name = "coptr"+ nextConstByteIdx++;
bindings.put(name, value);
return name;
}
} else if (value instanceof ConstantInteger) { } else if (value instanceof ConstantInteger) {
ConstantInteger intValue = (ConstantInteger) value; ConstantInteger intValue = (ConstantInteger) value;
if (intValue.getType().equals(SymbolTypeBasic.BYTE)) { if (SymbolTypeBasic.BYTE.equals(intValue.getType())) {
String name = "coby" + nextConstByteIdx++; String name = "coby" + nextConstByteIdx++;
bindings.put(name, value); bindings.put(name, value);
return name; return name;
} else if (intValue.getType().equals(SymbolTypeBasic.WORD)) { } else if (SymbolTypeBasic.WORD.equals(intValue.getType())) {
String name = "cowo" + nextConstByteIdx++; String name = "cowo" + nextConstByteIdx++;
bindings.put(name, value); bindings.put(name, value);
return name; return name;
@@ -234,6 +244,9 @@ public class AsmFragment {
*/ */
public String getBoundValue(String name) { public String getBoundValue(String name) {
Value boundValue = getBinding(name); Value boundValue = getBinding(name);
if(boundValue==null) {
throw new RuntimeException("Binding not found in fragment '" + name+"'");
}
String bound; String bound;
if (boundValue instanceof Variable) { if (boundValue instanceof Variable) {
RegisterAllocation.Register register = symbols.getRegister((Variable) boundValue); RegisterAllocation.Register register = symbols.getRegister((Variable) boundValue);
@@ -246,8 +259,8 @@ public class AsmFragment {
} else { } else {
throw new RuntimeException("Register Type not implemented " + register); throw new RuntimeException("Register Type not implemented " + register);
} }
} else if(boundValue instanceof PointerDereference) { } else if(boundValue instanceof PointerDereferenceVariable) {
PointerDereference deref = (PointerDereference) boundValue; PointerDereferenceVariable deref = (PointerDereferenceVariable) boundValue;
Variable pointer = deref.getPointer(); Variable pointer = deref.getPointer();
RegisterAllocation.Register register = symbols.getRegister(pointer); RegisterAllocation.Register register = symbols.getRegister(pointer);
if(register instanceof RegisterAllocation.RegisterZpPointerByte) { if(register instanceof RegisterAllocation.RegisterZpPointerByte) {
@@ -255,6 +268,15 @@ public class AsmFragment {
} else { } else {
throw new RuntimeException("Bound Value Type not implemented " + boundValue); throw new RuntimeException("Bound Value Type not implemented " + boundValue);
} }
} else if(boundValue instanceof PointerDereferenceConstant) {
PointerDereferenceConstant deref = (PointerDereferenceConstant) boundValue;
Constant pointer = deref.getPointer();
if (pointer instanceof ConstantInteger) {
ConstantInteger intPointer = (ConstantInteger) pointer;
bound = Integer.toString(intPointer.getNumber());
} else {
throw new RuntimeException("Bound Value Type not implemented " + boundValue);
}
} else if (boundValue instanceof ConstantInteger) { } else if (boundValue instanceof ConstantInteger) {
ConstantInteger boundInt = (ConstantInteger) boundValue; ConstantInteger boundInt = (ConstantInteger) boundValue;
if (boundInt.getType().equals(SymbolTypeBasic.BYTE)) { if (boundInt.getType().equals(SymbolTypeBasic.BYTE)) {

View File

@@ -0,0 +1,2 @@
lda #{coby2}
sta {coptr1}

View File

@@ -0,0 +1,2 @@
cpx #{coby1}
bcc {la1}

View File

@@ -0,0 +1,2 @@
lda {cowo1}
sta {zpby1}

View File

@@ -0,0 +1,3 @@
ldy #0
lda ({zpptrby1}),y
sta {zpby1}

View File

@@ -0,0 +1,3 @@
dex
stx {zpby1}
inx

View File

@@ -0,0 +1,4 @@
txa
sec
sbc #{coby1}
sta {zpby1}

View File

@@ -0,0 +1,3 @@
ldy #0
lda {zpby1}
sta ({zpiby1}),y

View File

@@ -0,0 +1,7 @@
txa
clc
adc #<{cowo1}
sta {zpptrby1}
lda #0
adc #>{cowo1}
sta {zpptrby1}+1

View File

@@ -0,0 +1,7 @@
lda #<{cowo1}
clc
adc {zpby1}
sta {zpptrby1}
lda #>{cowo1}
adc #0
sta {zpptrby1}+1

View File

@@ -165,7 +165,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
VariableIntermediate tmpVar = symbolTable.newIntermediateAssignment(); VariableIntermediate tmpVar = symbolTable.newIntermediateAssignment();
Statement stmt = new StatementAssignment(tmpVar, lval, operator, index); Statement stmt = new StatementAssignment(tmpVar, lval, operator, index);
sequence.addStatement(stmt); sequence.addStatement(stmt);
return new PointerDereference(tmpVar); return new PointerDereferenceVariable(tmpVar);
} }
@Override @Override
@@ -218,7 +218,10 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
VariableIntermediate tmpVar = symbolTable.newIntermediateAssignment(); VariableIntermediate tmpVar = symbolTable.newIntermediateAssignment();
Statement stmt = new StatementAssignment(tmpVar, array, operator, index); Statement stmt = new StatementAssignment(tmpVar, array, operator, index);
sequence.addStatement(stmt); sequence.addStatement(stmt);
return new PointerDereference(tmpVar); VariableIntermediate tmpVar2 = symbolTable.newIntermediateAssignment();
Statement stmt2 = new StatementAssignment(tmpVar2, null, new Operator("*"), tmpVar );
sequence.addStatement(stmt2);
return tmpVar2;
} }
@Override @Override

View File

@@ -5,7 +5,7 @@ import java.util.Iterator;
import java.util.Map; import java.util.Map;
/** Compiler Pass eliminating alias assignments */ /** Compiler Pass eliminating alias assignments */
public class Pass2AliasElimination extends Pass2Optimization { public class Pass2AliasElimination extends Pass2SsaOptimization {
public Pass2AliasElimination(ControlFlowGraph graph, SymbolTable symbolTable) { public Pass2AliasElimination(ControlFlowGraph graph, SymbolTable symbolTable) {
super(graph, symbolTable); super(graph, symbolTable);

View File

@@ -1,14 +1,13 @@
package dk.camelot64.kickc.icl; package dk.camelot64.kickc.icl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* Compiler Pass simplifying conditional jumps that are simple comparisons * Compiler Pass simplifying conditional jumps that are simple comparisons
*/ */
public class Pass2ConditionalJumpSimplification extends Pass2Optimization { public class Pass2ConditionalJumpSimplification extends Pass2SsaOptimization {
private Map<Variable, List<Statement>> allUsages; private Map<Variable, List<Statement>> allUsages;

View File

@@ -4,7 +4,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** Compiler Pass propagating constants in expressions eliminating constant variables */ /** Compiler Pass propagating constants in expressions eliminating constant variables */
public class Pass2ConstantPropagation extends Pass2Optimization { public class Pass2ConstantPropagation extends Pass2SsaOptimization {
public Pass2ConstantPropagation(ControlFlowGraph graph, SymbolTable symbolTable) { public Pass2ConstantPropagation(ControlFlowGraph graph, SymbolTable symbolTable) {
super(graph, symbolTable); super(graph, symbolTable);
@@ -47,7 +47,9 @@ public class Pass2ConstantPropagation extends Pass2Optimization {
} else { } else {
// Constant unary expression // Constant unary expression
Constant constant = calculateUnary(assignment.getOperator(), (Constant) assignment.getRValue2()); Constant constant = calculateUnary(assignment.getOperator(), (Constant) assignment.getRValue2());
constants.put(variable, constant); if(constant!=null) {
constants.put(variable, constant);
}
} }
} else if (assignment.getRValue1() instanceof Constant && assignment.getRValue2() instanceof Constant) { } else if (assignment.getRValue1() instanceof Constant && assignment.getRValue2() instanceof Constant) {
// Constant binary expression // Constant binary expression
@@ -141,6 +143,9 @@ public class Pass2ConstantPropagation extends Pass2Optimization {
case "+": { case "+": {
return c; return c;
} }
case "*": { // pointer dereference
return null;
}
default: default:
throw new RuntimeException("Unhandled Unary Operator " + operator.getOperator()); throw new RuntimeException("Unhandled Unary Operator " + operator.getOperator());
} }

View File

@@ -3,7 +3,7 @@ package dk.camelot64.kickc.icl;
import java.util.*; import java.util.*;
/** Pass that culls empty control flow blocks from the program */ /** Pass that culls empty control flow blocks from the program */
public class Pass2CullEmptyBlocks extends Pass2Optimization { public class Pass2CullEmptyBlocks extends Pass2SsaOptimization {
public Pass2CullEmptyBlocks(ControlFlowGraph graph, SymbolTable symbolTable) { public Pass2CullEmptyBlocks(ControlFlowGraph graph, SymbolTable symbolTable) {
super(graph, symbolTable); super(graph, symbolTable);

View File

@@ -4,7 +4,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** Compiler Pass eliminating redundant phi functions */ /** Compiler Pass eliminating redundant phi functions */
public class Pass2RedundantPhiElimination extends Pass2Optimization{ public class Pass2RedundantPhiElimination extends Pass2SsaOptimization {
public Pass2RedundantPhiElimination(ControlFlowGraph graph, SymbolTable symbolTable) { public Pass2RedundantPhiElimination(ControlFlowGraph graph, SymbolTable symbolTable) {
super(graph, symbolTable); super(graph, symbolTable);

View File

@@ -1,11 +1,9 @@
package dk.camelot64.kickc.icl; package dk.camelot64.kickc.icl;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map;
/** Compiler Pass eliminating phi self assignments */ /** Compiler Pass eliminating phi self assignments */
public class Pass2SelfPhiElimination extends Pass2Optimization{ public class Pass2SelfPhiElimination extends Pass2SsaOptimization {
public Pass2SelfPhiElimination(ControlFlowGraph graph, SymbolTable symbolTable) { public Pass2SelfPhiElimination(ControlFlowGraph graph, SymbolTable symbolTable) {
super(graph, symbolTable); super(graph, symbolTable);

View File

@@ -3,15 +3,15 @@ package dk.camelot64.kickc.icl;
import java.util.*; import java.util.*;
/** /**
* Optimization performed during Compiler Pass 2. * Optimization on Single Static Assignment form (Control Flow Graph) performed during Compiler Pass 2.
* Optimizations are performed repeatedly until none of them yield any result * Optimizations are performed repeatedly until none of them yield any result
* */ */
public abstract class Pass2Optimization { public abstract class Pass2SsaOptimization {
private ControlFlowGraph graph; private ControlFlowGraph graph;
private SymbolTable symbolTable; private SymbolTable symbolTable;
public Pass2Optimization(ControlFlowGraph graph, SymbolTable symbolTable) { public Pass2SsaOptimization(ControlFlowGraph graph, SymbolTable symbolTable) {
this.graph = graph; this.graph = graph;
this.symbolTable = symbolTable; this.symbolTable = symbolTable;
} }
@@ -31,7 +31,9 @@ public abstract class Pass2Optimization {
*/ */
public abstract boolean optimize(); public abstract boolean optimize();
/** Singleton signalling that an RValue is never assigned and can safely be discarded as rvalue in phi-functions.*/ /**
* Singleton signalling that an RValue is never assigned and can safely be discarded as rvalue in phi-functions.
*/
public static RValue VOID = new RValue() { public static RValue VOID = new RValue() {
@Override @Override
public String toString() { public String toString() {
@@ -41,33 +43,52 @@ public abstract class Pass2Optimization {
/** /**
* Replace all usages of variables in statements with aliases. * Replace all usages of variables in statements with aliases.
*
* @param aliases Variables that have alias values. * @param aliases Variables that have alias values.
*/ */
public void replaceVariables(final Map<Variable, ? extends RValue> aliases) { public void replaceVariables(final Map<Variable, ? extends RValue> aliases) {
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() { ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
@Override @Override
public Void visitAssignment(StatementAssignment assignment) { public Void visitAssignment(StatementAssignment assignment) {
if(getAlias(aliases, assignment.getLValue()) !=null) { LValue lValue = assignment.getLValue();
RValue alias = getAlias(aliases, assignment.getLValue()); if (getAlias(aliases, lValue) != null) {
if(alias instanceof LValue) { RValue alias = getAlias(aliases, lValue);
if (alias instanceof LValue) {
assignment.setLValue((LValue) alias); assignment.setLValue((LValue) alias);
} else {
throw new RuntimeException("Error replacing LValue variable " + lValue + " with " + alias);
} }
} }
if(getAlias(aliases, assignment.getRValue1())!=null) { if (getAlias(aliases, assignment.getRValue1()) != null) {
assignment.setRValue1(getAlias(aliases, assignment.getRValue1())); assignment.setRValue1(getAlias(aliases, assignment.getRValue1()));
} }
if(getAlias(aliases, assignment.getRValue2())!=null) { if (getAlias(aliases, assignment.getRValue2()) != null) {
assignment.setRValue2(getAlias(aliases, assignment.getRValue2())); assignment.setRValue2(getAlias(aliases, assignment.getRValue2()));
} }
// Handle pointer dereference in LValue
if (lValue instanceof PointerDereferenceVariable) {
PointerDereferenceVariable deref = (PointerDereferenceVariable) lValue;
Variable pointer = deref.getPointer();
if (getAlias(aliases, pointer) != null) {
RValue alias = getAlias(aliases, pointer);
if (alias instanceof Variable) {
deref.setPointerVariable((Variable) alias);
} else if (alias instanceof Constant) {
assignment.setLValue(new PointerDereferenceConstant((Constant) alias));
} else {
throw new RuntimeException("Error replacing LValue variable " + lValue + " with " + alias);
}
}
}
return null; return null;
} }
@Override @Override
public Void visitConditionalJump(StatementConditionalJump conditionalJump) { public Void visitConditionalJump(StatementConditionalJump conditionalJump) {
if(getAlias(aliases, conditionalJump.getRValue1())!=null) { if (getAlias(aliases, conditionalJump.getRValue1()) != null) {
conditionalJump.setRValue1(getAlias(aliases, conditionalJump.getRValue1())); conditionalJump.setRValue1(getAlias(aliases, conditionalJump.getRValue1()));
} }
if(getAlias(aliases, conditionalJump.getRValue2())!=null) { if (getAlias(aliases, conditionalJump.getRValue2()) != null) {
conditionalJump.setRValue2(getAlias(aliases, conditionalJump.getRValue2())); conditionalJump.setRValue2(getAlias(aliases, conditionalJump.getRValue2()));
} }
return null; return null;
@@ -75,9 +96,9 @@ public abstract class Pass2Optimization {
@Override @Override
public Void visitPhi(StatementPhi phi) { public Void visitPhi(StatementPhi phi) {
if(getAlias(aliases, phi.getLValue())!=null) { if (getAlias(aliases, phi.getLValue()) != null) {
RValue alias = getAlias(aliases, phi.getLValue()); RValue alias = getAlias(aliases, phi.getLValue());
if(alias instanceof LValue) { if (alias instanceof LValue) {
phi.setLValue((Variable) alias); phi.setLValue((Variable) alias);
} }
} }
@@ -98,15 +119,16 @@ public abstract class Pass2Optimization {
visitor.visitGraph(graph); visitor.visitGraph(graph);
} }
/** Get the alias to use for an RValue. /**
* Get the alias to use for an RValue.
* *
* @param aliases The alias map * @param aliases The alias map
* @param rValue The RValue to find an alias for * @param rValue The RValue to find an alias for
* @return The alias to use. Null if no alias exists. * @return The alias to use. Null if no alias exists.
*/ */
private static RValue getAlias(Map<Variable, ? extends RValue> aliases,RValue rValue) { private static RValue getAlias(Map<Variable, ? extends RValue> aliases, RValue rValue) {
RValue alias = aliases.get(rValue); RValue alias = aliases.get(rValue);
while (aliases.get(alias)!=null) { while (aliases.get(alias) != null) {
alias = aliases.get(alias); alias = aliases.get(alias);
} }
return alias; return alias;
@@ -114,14 +136,15 @@ public abstract class Pass2Optimization {
/** /**
* Replace all usages of a label in statements with another label. * Replace all usages of a label in statements with another label.
*
* @param replacements Variables that have alias values. * @param replacements Variables that have alias values.
*/ */
public void replaceLabels(final Map<Label, Label> replacements) { public void replaceLabels(final Map<Label, Label> replacements) {
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() { ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
@Override @Override
public Void visitConditionalJump(StatementConditionalJump conditionalJump) { public Void visitConditionalJump(StatementConditionalJump conditionalJump) {
if(getReplacement(replacements, conditionalJump.getDestination())!=null) { if (getReplacement(replacements, conditionalJump.getDestination()) != null) {
conditionalJump.setDestination(getReplacement(replacements, conditionalJump.getDestination())); conditionalJump.setDestination(getReplacement(replacements, conditionalJump.getDestination()));
} }
return null; return null;
@@ -129,7 +152,7 @@ public abstract class Pass2Optimization {
@Override @Override
public Void visitJump(StatementJump jump) { public Void visitJump(StatementJump jump) {
if(getReplacement(replacements, jump.getDestination())!=null) { if (getReplacement(replacements, jump.getDestination()) != null) {
jump.setDestination(getReplacement(replacements, jump.getDestination())); jump.setDestination(getReplacement(replacements, jump.getDestination()));
} }
return null; return null;
@@ -139,7 +162,7 @@ public abstract class Pass2Optimization {
public Void visitPhi(StatementPhi phi) { public Void visitPhi(StatementPhi phi) {
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) { for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
Label replacement = getReplacement(replacements, previousSymbol.getBlock().getLabel()); Label replacement = getReplacement(replacements, previousSymbol.getBlock().getLabel());
if(replacement !=null) { if (replacement != null) {
previousSymbol.setBlock(graph.getBlock(replacement)); previousSymbol.setBlock(graph.getBlock(replacement));
} }
} }
@@ -149,15 +172,16 @@ public abstract class Pass2Optimization {
visitor.visitGraph(graph); visitor.visitGraph(graph);
} }
/** Get the label to use as replacement for another label. /**
* Get the label to use as replacement for another label.
* *
* @param replacements The label replacement map * @param replacements The label replacement map
* @param label The label to find a replacement for * @param label The label to find a replacement for
* @return The alias to use. Null if no replacement exists. * @return The alias to use. Null if no replacement exists.
*/ */
private static Label getReplacement(Map<Label, Label> replacements,Label label) { private static Label getReplacement(Map<Label, Label> replacements, Label label) {
Label replacement = replacements.get(label); Label replacement = replacements.get(label);
while (replacements.get(replacement)!=null) { while (replacements.get(replacement) != null) {
replacement = replacements.get(replacement); replacement = replacements.get(replacement);
} }
return replacement; return replacement;
@@ -166,6 +190,7 @@ public abstract class Pass2Optimization {
/** /**
* Remove all assignments to specific LValues from the control flow graph (as they are no longer needed). * Remove all assignments to specific LValues from the control flow graph (as they are no longer needed).
*
* @param variables The variables to eliminate * @param variables The variables to eliminate
*/ */
public void removeAssignments(Collection<? extends LValue> variables) { public void removeAssignments(Collection<? extends LValue> variables) {
@@ -177,7 +202,7 @@ public abstract class Pass2Optimization {
if (variables.contains(assignment.getLValue())) { if (variables.contains(assignment.getLValue())) {
iterator.remove(); iterator.remove();
} }
} else if(statement instanceof StatementPhi) { } else if (statement instanceof StatementPhi) {
StatementPhi phi = (StatementPhi) statement; StatementPhi phi = (StatementPhi) statement;
if (variables.contains(phi.getLValue())) { if (variables.contains(phi.getLValue())) {
iterator.remove(); iterator.remove();
@@ -189,6 +214,7 @@ public abstract class Pass2Optimization {
/** /**
* Remove variables from the symbol table * Remove variables from the symbol table
*
* @param variables The variables to remove * @param variables The variables to remove
*/ */
public void deleteSymbols(Collection<? extends LValue> variables) { public void deleteSymbols(Collection<? extends LValue> variables) {

View File

@@ -0,0 +1,33 @@
package dk.camelot64.kickc.icl;
import dk.camelot64.kickc.asm.AsmLine;
import dk.camelot64.kickc.asm.AsmProgram;
import java.util.Iterator;
import java.util.List;
/** Optimization performed on Assembler Code (Asm Code).
* Optimizations are performed repeatedly until none of them yield any result
**/
public class Pass5AsmOptimization {
private AsmProgram program;
public Pass5AsmOptimization(AsmProgram program) {
this.program = program;
}
public AsmProgram getProgram() {
return program;
}
public void remove(List<AsmLine> remove) {
for (Iterator<AsmLine> iterator = program.getLines().iterator(); iterator.hasNext(); ) {
AsmLine line = iterator.next();
if (remove.contains(line)) {
System.out.println("Removing instruction "+line.getAsm());
iterator.remove();
}
}
}
}

View File

@@ -10,23 +10,20 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
/** Optimize assembler code by removing jumps to labels immediately following the jump */ /** Optimize assembler code by removing jumps to labels immediately following the jump */
public class Pass5NextJumpElimination { public class Pass5NextJumpElimination extends Pass5AsmOptimization {
private AsmProgram program;
public Pass5NextJumpElimination(AsmProgram program) { public Pass5NextJumpElimination(AsmProgram program) {
this.program = program; super(program);
} }
public boolean optimize() { public boolean optimize() {
List<AsmLine> remove = new ArrayList<>(); List<AsmLine> removeLines = new ArrayList<>();
AsmInstruction candidate = null; AsmInstruction candidate = null;
for (AsmLine line : program.getLines()) { for (AsmLine line : getProgram().getLines()) {
if(candidate!=null) { if(candidate!=null) {
if(line instanceof AsmLabel) { if(line instanceof AsmLabel) {
if(((AsmLabel) line).getLabel().equals(candidate.getParameter())) { if(((AsmLabel) line).getLabel().equals(candidate.getParameter())) {
remove.add(candidate); removeLines.add(candidate);
candidate = null;
} }
} }
} }
@@ -38,13 +35,7 @@ public class Pass5NextJumpElimination {
} }
} }
} }
for (Iterator<AsmLine> iterator = program.getLines().iterator(); iterator.hasNext(); ) { remove(removeLines);
AsmLine line = iterator.next(); return removeLines.size()>0;
if (remove.contains(line)) {
System.out.println("Removing jump to next instruction "+line.getAsm());
iterator.remove();
}
}
return remove.size()>0;
} }
} }

View File

@@ -18,7 +18,8 @@ public class PassTypeInference {
if (operator == null || assignment.getRValue1() == null) { if (operator == null || assignment.getRValue1() == null) {
// Copy operation or Unary operation // Copy operation or Unary operation
RValue rValue = assignment.getRValue2(); RValue rValue = assignment.getRValue2();
SymbolType type = inferType(rValue); SymbolType subType = inferType(rValue);
SymbolType type = inferType(operator, subType);
symbol.setInferredType(type); symbol.setInferredType(type);
} else { } else {
// Binary operation // Binary operation
@@ -33,6 +34,23 @@ public class PassTypeInference {
} }
} }
private SymbolType inferType(Operator operator, SymbolType subType) {
if(operator==null) {
return subType;
}
String op = operator.getOperator();
switch (op) {
case "*":
if(subType instanceof SymbolTypePointer) {
return ((SymbolTypePointer) subType).getElementType();
} else {
throw new RuntimeException("Type error: Dereferencing a non-pointer "+subType);
}
default:
return subType;
}
}
private SymbolType inferType(SymbolType type1, Operator operator, SymbolType type2) { private SymbolType inferType(SymbolType type1, Operator operator, SymbolType type2) {
String op = operator.getOperator(); String op = operator.getOperator();
switch (op) { switch (op) {
@@ -55,7 +73,15 @@ public class PassTypeInference {
if (type1 instanceof SymbolTypePointer && (type2.equals(SymbolTypeBasic.BYTE) || type2.equals(SymbolTypeBasic.WORD))) { if (type1 instanceof SymbolTypePointer && (type2.equals(SymbolTypeBasic.BYTE) || type2.equals(SymbolTypeBasic.WORD))) {
return new SymbolTypePointer(((SymbolTypePointer) type1).getElementType()); return new SymbolTypePointer(((SymbolTypePointer) type1).getElementType());
} }
if (type1 instanceof SymbolTypePointer && type2 instanceof SymbolTypePointer) {
SymbolType elmType1 = ((SymbolTypePointer) type1).getElementType();
SymbolType elmType2 = ((SymbolTypePointer) type2).getElementType();
return inferType(elmType1, operator, elmType2);
}
case "*": case "*":
if(type1==null && type2 instanceof SymbolTypePointer) {
return ((SymbolTypePointer) type2).getElementType();
}
case "/": case "/":
if (SymbolTypeBasic.WORD.equals(type1) || SymbolTypeBasic.WORD.equals(type2)) { if (SymbolTypeBasic.WORD.equals(type1) || SymbolTypeBasic.WORD.equals(type2)) {
return SymbolTypeBasic.WORD; return SymbolTypeBasic.WORD;

View File

@@ -1,20 +1,8 @@
package dk.camelot64.kickc.icl; package dk.camelot64.kickc.icl;
/** A dereferenced pointer */ /** A dereferenced pointer */
public class PointerDereference implements LValue { public interface PointerDereference extends LValue {
private Variable pointer; Value getPointer();
public PointerDereference(Variable pointer) {
this.pointer = pointer;
}
public Variable getPointer() {
return pointer;
}
@Override
public String toString() {
return "*(" + pointer + ')';
}
} }

View File

@@ -0,0 +1,24 @@
package dk.camelot64.kickc.icl;
/** A dereferenced constant pointer */
public class PointerDereferenceConstant implements LValue {
private Constant pointer;
public PointerDereferenceConstant(Constant pointer) {
this.pointer = pointer;
}
public Constant getPointer() {
return pointer;
}
public Constant getPointerConstant() {
return pointer;
}
@Override
public String toString() {
return "*(" + pointer + ')';
}
}

View File

@@ -0,0 +1,28 @@
package dk.camelot64.kickc.icl;
/** A dereferenced variable pointer */
public class PointerDereferenceVariable implements PointerDereference {
private Variable pointer;
public PointerDereferenceVariable(Variable pointer) {
this.pointer = pointer;
}
public Variable getPointer() {
return pointer;
}
public Variable getPointerVariable() {
return pointer;
}
@Override
public String toString() {
return "*(" + pointer + ')';
}
public void setPointerVariable(Variable pointer) {
this.pointer = pointer;
}
}

View File

@@ -13,7 +13,7 @@ import java.util.List;
/** Test my KickC Grammar */ /** Test my KickC Grammar */
public class Main { public class Main {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
final String fileName = "src/dk/camelot64/kickc/test/mem.kc"; final String fileName = "src/dk/camelot64/kickc/test/fibmem.kc";
final CharStream input = CharStreams.fromFileName(fileName); final CharStream input = CharStreams.fromFileName(fileName);
System.out.println(input.toString()); System.out.println(input.toString());
KickCLexer lexer = new KickCLexer(input); KickCLexer lexer = new KickCLexer(input);
@@ -42,7 +42,7 @@ public class Main {
new Pass1GenerateSingleStaticAssignmentForm(symbolTable, controlFlowGraph); new Pass1GenerateSingleStaticAssignmentForm(symbolTable, controlFlowGraph);
pass1GenerateSingleStaticAssignmentForm.generate(); pass1GenerateSingleStaticAssignmentForm.generate();
List<Pass2Optimization> optimizations = new ArrayList<>(); List<Pass2SsaOptimization> optimizations = new ArrayList<>();
optimizations.add(new Pass2CullEmptyBlocks(controlFlowGraph, symbolTable)); optimizations.add(new Pass2CullEmptyBlocks(controlFlowGraph, symbolTable));
optimizations.add(new Pass2ConstantPropagation(controlFlowGraph, symbolTable)); optimizations.add(new Pass2ConstantPropagation(controlFlowGraph, symbolTable));
optimizations.add(new Pass2AliasElimination(controlFlowGraph, symbolTable)); optimizations.add(new Pass2AliasElimination(controlFlowGraph, symbolTable));
@@ -53,14 +53,14 @@ public class Main {
System.out.println("INITIAL CONTROL FLOW GRAPH"); System.out.println("INITIAL CONTROL FLOW GRAPH");
System.out.println(controlFlowGraph.toString()); System.out.println(controlFlowGraph.toString());
boolean optimized = true; boolean ssaOptimized = true;
while (optimized) { while (ssaOptimized) {
optimized = false; ssaOptimized = false;
for (Pass2Optimization optimization : optimizations) { for (Pass2SsaOptimization optimization : optimizations) {
boolean stepOptimized = optimization.optimize(); boolean stepOptimized = optimization.optimize();
if (stepOptimized) { if (stepOptimized) {
System.out.println("Succesful optimization "+optimization); System.out.println("Succesful optimization "+optimization);
optimized = true; ssaOptimized = true;
System.out.println("CONTROL FLOW GRAPH"); System.out.println("CONTROL FLOW GRAPH");
System.out.println(controlFlowGraph.toString()); System.out.println(controlFlowGraph.toString());
} }
@@ -73,7 +73,10 @@ public class Main {
Pass4CodeGeneration pass4CodeGeneration = new Pass4CodeGeneration(controlFlowGraph, symbolTable); Pass4CodeGeneration pass4CodeGeneration = new Pass4CodeGeneration(controlFlowGraph, symbolTable);
AsmProgram asmProgram = pass4CodeGeneration.generate(); AsmProgram asmProgram = pass4CodeGeneration.generate();
Pass5NextJumpElimination pass5NextJumpElimination = new Pass5NextJumpElimination(asmProgram); Pass5NextJumpElimination pass5NextJumpElimination = new Pass5NextJumpElimination(asmProgram);
pass5NextJumpElimination.optimize(); boolean asmOptimized = true;
while(asmOptimized) {
asmOptimized = pass5NextJumpElimination.optimize();
}
System.out.println("SYMBOLS"); System.out.println("SYMBOLS");

View File

@@ -0,0 +1,8 @@
byte[15] fibs = $1100;
fibs[0] = 0;
fibs[1] = 1;
byte i = 2;
while(i<15) {
fibs[i] = fibs[i-2]+fibs[i-1];
i = i + 1;
}