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

Added *idx operator for array indexing.

This commit is contained in:
jespergravgaard 2017-06-03 23:49:06 +02:00
parent 65f41f874f
commit 357bbecade
8 changed files with 120 additions and 40 deletions

View File

@ -109,6 +109,8 @@ public class AsmFragment {
switch (op) {
case "*":
return "_star_";
case "*idx":
return "_staridx_";
case "+":
return "_plus_";
case "-":

View File

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

View File

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

View File

@ -216,14 +216,11 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
public RValue visitExprArray(KickCParser.ExprArrayContext ctx) {
RValue array = (LValue) visit(ctx.expr(0));
RValue index = (RValue) visit(ctx.expr(1));
Operator operator = new Operator("+");
Operator operator = new Operator("*idx");
VariableIntermediate tmpVar = symbolTable.newIntermediateAssignment();
Statement stmt = new StatementAssignment(tmpVar, array, operator, index);
sequence.addStatement(stmt);
VariableIntermediate tmpVar2 = symbolTable.newIntermediateAssignment();
Statement stmt2 = new StatementAssignment(tmpVar2, null, new Operator("*"), tmpVar );
sequence.addStatement(stmt2);
return tmpVar2;
return tmpVar;
}
@Override

View File

@ -1,6 +1,8 @@
package dk.camelot64.kickc.icl;
/** Compiler Pass eliminating several additions of constants by consolidating them to a single (compile time) constant c1+v+c2 => (c1+c2)+v */
/**
* Compiler Pass eliminating several additions of constants by consolidating them to a single (compile time) constant c1+v+c2 => (c1+c2)+v
*/
public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
public Pass2ConstantAdditionElimination(ControlFlowGraph graph, SymbolTable symbolTable) {
@ -9,6 +11,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
/**
* For assignments with a constant part the variable part is examined looking for constants to consolidate into the constant.
*
* @return true optimization was performed. false if no optimization was possible.
*/
@Override
@ -17,49 +20,88 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
// Examine all assigments - performing constant consolidation
for (ControlFlowBlock block : getGraph().getAllBlocks()) {
for (Statement statement : block.getStatements()) {
if(statement instanceof StatementAssignment) {
if (statement instanceof StatementAssignment) {
boolean subOpt = false;
StatementAssignment assignment = (StatementAssignment) statement;
if(assignment.getOperator()!=null && "+".equals(assignment.getOperator().getOperator())) {
if(assignment.getRValue1() instanceof ConstantInteger && assignment.getRValue2() instanceof Variable) {
Variable variable = (Variable) assignment.getRValue2();
ConstantInteger consolidated = consolidateSubConstants(variable);
if(consolidated!=null) {
ConstantInteger const1 = (ConstantInteger) assignment.getRValue1();
assignment.setRValue1(new ConstantInteger(const1.getNumber()+consolidated.getNumber()));
optimized = true;
System.out.println("Consolidated constant in assignment "+assignment.getLValue());
}
} else if(assignment.getRValue1() instanceof Variable && assignment.getRValue2() instanceof ConstantInteger) {
Variable variable = (Variable) assignment.getRValue1();
ConstantInteger consolidated = consolidateSubConstants(variable);
if(consolidated!=null) {
ConstantInteger const2 = (ConstantInteger) assignment.getRValue2();
assignment.setRValue2(new ConstantInteger(const2.getNumber()+consolidated.getNumber()));
optimized = true;
System.out.println("Consolidated constant in assignment "+assignment.getLValue());
}
Operator operator = assignment.getOperator();
if (operator != null) {
switch (operator.getOperator()) {
case "+":
subOpt = optimizePlus(assignment);
break;
case "*idx":
subOpt = optimizeArrayDeref(assignment);
break;
}
}
if (subOpt) {
optimized = true;
}
}
}
}
return optimized;
}
private boolean optimizeArrayDeref(StatementAssignment assignment) {
if (assignment.getRValue1() instanceof ConstantInteger && assignment.getRValue2() instanceof Variable) {
Variable variable = (Variable) assignment.getRValue2();
ConstantInteger consolidated = consolidateSubConstants(variable);
if (consolidated != null) {
ConstantInteger ptrConstant = (ConstantInteger) assignment.getRValue1();
int newPtr = ptrConstant.getNumber() + consolidated.getNumber();
assignment.setRValue1(new ConstantInteger(newPtr));
System.out.println("Consolidated constant in assignment " + assignment.getLValue());
return true;
}
}
return false;
}
private boolean optimizePlus(StatementAssignment assignment) {
if (assignment.getRValue1() instanceof ConstantInteger && assignment.getRValue2() instanceof Variable) {
Variable variable = (Variable) assignment.getRValue2();
ConstantInteger consolidated = consolidateSubConstants(variable);
if (consolidated != null) {
ConstantInteger const1 = (ConstantInteger) assignment.getRValue1();
assignment.setRValue1(new ConstantInteger(const1.getNumber() + consolidated.getNumber()));
System.out.println("Consolidated constant in assignment " + assignment.getLValue());
return true;
}
} else if (assignment.getRValue1() instanceof Variable && assignment.getRValue2() instanceof ConstantInteger) {
Variable variable = (Variable) assignment.getRValue1();
ConstantInteger consolidated = consolidateSubConstants(variable);
if (consolidated != null) {
ConstantInteger const2 = (ConstantInteger) assignment.getRValue2();
int newNumber = const2.getNumber() + consolidated.getNumber();
if (newNumber < 0) {
assignment.setRValue2(new ConstantInteger(-newNumber));
assignment.setOperator(new Operator("-"));
} else {
assignment.setRValue2(new ConstantInteger(newNumber));
}
System.out.println("Consolidated constant in assignment " + assignment.getLValue());
return true;
}
}
return false;
}
/**
* Gather up constants from sub addition expressions of a variable, remove them there, and return the aggregated sum.
*
* @param variable The variable to examine
* @return The consolidated constant. Null if no sub-constants were found.
*/
private ConstantInteger consolidateSubConstants(Variable variable) {
StatementAssignment assignment = getGraph().getAssignment(variable);
if(assignment!=null && assignment.getOperator()!=null && "+".equals(assignment.getOperator().getOperator())) {
if(assignment.getRValue1() instanceof ConstantInteger) {
if (assignment != null && assignment.getOperator() != null && "+".equals(assignment.getOperator().getOperator())) {
if (assignment.getRValue1() instanceof ConstantInteger) {
ConstantInteger constant = (ConstantInteger) assignment.getRValue1();
assignment.setRValue1(null);
assignment.setOperator(null);
return constant;
} else if(assignment.getRValue2() instanceof ConstantInteger) {
} else if (assignment.getRValue2() instanceof ConstantInteger) {
ConstantInteger constant = (ConstantInteger) assignment.getRValue2();
assignment.setRValue2(assignment.getRValue1());
assignment.setOperator(null);
@ -67,20 +109,52 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
return constant;
} else {
ConstantInteger const1 = null;
if(assignment.getRValue1() instanceof Variable) {
if (assignment.getRValue1() instanceof Variable) {
const1 = consolidateSubConstants((Variable) assignment.getRValue1());
}
ConstantInteger const2 = null;
if(assignment.getRValue2() instanceof Variable) {
if (assignment.getRValue2() instanceof Variable) {
const2 = consolidateSubConstants((Variable) assignment.getRValue2());
}
ConstantInteger result = null;
if(const1!=null) {
if (const1 != null) {
result = const1;
if(const2!=null) {
result = new ConstantInteger(const1.getNumber()+const2.getNumber());
if (const2 != null) {
result = new ConstantInteger(const1.getNumber() + const2.getNumber());
}
} else if(const2!=null) {
} else if (const2 != null) {
result = const2;
}
return result;
}
}
if (assignment != null && assignment.getOperator() != null && "-".equals(assignment.getOperator().getOperator())) {
if (assignment.getRValue1() instanceof ConstantInteger) {
ConstantInteger constant = (ConstantInteger) assignment.getRValue1();
assignment.setRValue1(null);
return constant;
} else if (assignment.getRValue2() instanceof ConstantInteger) {
ConstantInteger constant = (ConstantInteger) assignment.getRValue2();
assignment.setRValue2(assignment.getRValue1());
assignment.setOperator(null);
assignment.setRValue1(null);
return new ConstantInteger(-constant.getNumber());
} else {
ConstantInteger const1 = null;
if (assignment.getRValue1() instanceof Variable) {
const1 = consolidateSubConstants((Variable) assignment.getRValue1());
}
ConstantInteger const2 = null;
if (assignment.getRValue2() instanceof Variable) {
const2 = consolidateSubConstants((Variable) assignment.getRValue2());
}
ConstantInteger result = null;
if (const1 != null) {
result = const1;
if (const2 != null) {
result = new ConstantInteger(const1.getNumber() - const2.getNumber());
}
} else if (const2 != null) {
result = const2;
}
return result;
@ -89,5 +163,4 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
return null;
}
}

View File

@ -94,6 +94,11 @@ public class PassTypeInference {
return SymbolTypeBasic.BYTE;
}
throw new RuntimeException("Type inference case not handled " + type1 + " " + operator + " " + type2);
case "*idx":
if(type1 instanceof SymbolTypePointer) {
return ((SymbolTypePointer) type1).getElementType();
}
throw new RuntimeException("Type inference case not handled " + type1 + " " + operator + " " + type2);
case "/":
if (SymbolTypeBasic.WORD.equals(type1) || SymbolTypeBasic.WORD.equals(type2)) {
return SymbolTypeBasic.WORD;

View File

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

View File

@ -1,7 +1,6 @@
byte[16] p = $1100;
byte i = 5;
do {
byte c=2;
p[i] = 15+i+c+i+2;
p[i] = 2+i+2;
i = i+1;
} while(i<10)