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

Cleaned up RValue hierarchy. Removing redundant Constant interface. Moving ConstantVar out of the value-hierarchy.

This commit is contained in:
jespergravgaard 2017-10-17 11:35:37 +02:00
parent efc750ce11
commit feba0565b4
14 changed files with 92 additions and 97 deletions

View File

@ -80,12 +80,9 @@ public class AsmFragment {
*
* @return The ASM string representing the constant value
*/
public static String getAsmConstant(Program program, Constant value, int precedence) {
public static String getAsmConstant(Program program, ConstantValue value, int precedence) {
if (value instanceof ConstantRef) {
value = program.getScope().getConstant((ConstantRef) value);
}
if (value instanceof ConstantVar) {
ConstantVar constantVar = (ConstantVar) value;
ConstantVar constantVar = program.getScope().getConstant((ConstantRef) value);
String asmName = constantVar.getAsmName() == null ? constantVar.getLocalName() : constantVar.getAsmName();
return asmName.replace("#", "_").replace("$", "_");
} else if (value instanceof ConstantInteger) {
@ -421,8 +418,8 @@ public class AsmFragment {
} else if (boundValue instanceof PointerDereferenceSimple) {
PointerDereferenceSimple deref = (PointerDereferenceSimple) boundValue;
RValue pointer = deref.getPointer();
if (pointer instanceof Constant) {
Constant pointerConst = (Constant) pointer;
if (pointer instanceof ConstantValue) {
ConstantValue pointerConst = (ConstantValue) pointer;
if (pointerConst instanceof ConstantInteger) {
ConstantInteger intPointer = (ConstantInteger) pointerConst;
String param = getAsmNumber(intPointer.getNumber());
@ -433,8 +430,13 @@ public class AsmFragment {
} else {
throw new RuntimeException("Bound Value Type not implemented " + boundValue);
}
} else if (boundValue instanceof Constant) {
Constant boundConst = (Constant) boundValue;
} else if (boundValue instanceof ConstantVar) {
ConstantVar constantVar = (ConstantVar) boundValue;
String constantValueAsm = getAsmConstant(program, constantVar.getRef(), 99);
boolean constantValueZp = SymbolTypeBasic.BYTE.equals(constantVar.getType(program.getScope()));
return new AsmParameter(constantValueAsm, constantValueZp);
} else if (boundValue instanceof ConstantValue) {
ConstantValue boundConst = (ConstantValue) boundValue;
String constantValueAsm = getAsmConstant(program, boundConst, 99);
boolean constantValueZp = SymbolTypeBasic.BYTE.equals(boundConst.getType(program.getScope()));
return new AsmParameter(constantValueAsm, constantValueZp);
@ -442,7 +444,7 @@ public class AsmFragment {
String param = ((Label) boundValue).getLocalName().replace('@', 'b').replace(':', '_').replace("$", "_");
return new AsmParameter(param, false);
} else {
throw new RuntimeException("Bound Value Type not implemented " + boundValue);
throw new RuntimeException("Bound Value Type not implemented " + boundValue);
}
}

View File

@ -1,8 +0,0 @@
package dk.camelot64.kickc.model;
/** SSA form constant value */
public interface Constant extends RValue {
SymbolType getType(ProgramScope scope);
}

View File

@ -4,15 +4,15 @@ package dk.camelot64.kickc.model;
public class ConstantBinary implements ConstantValue {
/** The left constant operand. */
private Constant left;
private ConstantValue left;
/** The operator, */
private Operator operator;
/** The right constant operand. */
private Constant right;
private ConstantValue right;
public ConstantBinary(Constant left, Operator operator, Constant right) {
public ConstantBinary(ConstantValue left, Operator operator, ConstantValue right) {
this.left = left;
this.operator = operator;
this.right = right;
@ -22,11 +22,11 @@ public class ConstantBinary implements ConstantValue {
return operator;
}
public Constant getLeft() {
public ConstantValue getLeft() {
return left;
}
public Constant getRight() {
public ConstantValue getRight() {
return right;
}

View File

@ -7,9 +7,9 @@ public class ConstantUnary implements ConstantValue {
private Operator operator;
/** The constant operand. */
private Constant operand;
private ConstantValue operand;
public ConstantUnary(Operator operator, Constant operand) {
public ConstantUnary(Operator operator, ConstantValue operand) {
this.operator = operator;
this.operand = operand;
}
@ -18,7 +18,7 @@ public class ConstantUnary implements ConstantValue {
return operator;
}
public Constant getOperand() {
public ConstantValue getOperand() {
return operand;
}

View File

@ -1,6 +1,8 @@
package dk.camelot64.kickc.model;
/** A constant value. The value might be calculated through a constant expression. */
public interface ConstantValue extends Constant {
public interface ConstantValue extends RValue {
SymbolType getType(ProgramScope scope);
}

View File

@ -3,7 +3,7 @@ package dk.camelot64.kickc.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
/** A named constant or a variable that has been inferred to be constant in the symbol table */
public class ConstantVar implements Constant, Symbol {
public class ConstantVar implements Symbol {
/** The name of the variable. */
private String name;
@ -29,7 +29,6 @@ public class ConstantVar implements Constant, Symbol {
this.value = value;
}
@Override
public SymbolType getType(ProgramScope scope) {
return type;
}

View File

@ -179,7 +179,7 @@ public class VariableReferenceInfo {
private Collection<VariableRef> getReferenced(RValue rValue) {
if (rValue == null) {
return new ArrayList<>();
} else if (rValue instanceof Constant) {
} else if (rValue instanceof ConstantValue) {
return new ArrayList<>();
} else if (rValue instanceof PointerDereferenceSimple) {
return getReferenced(((PointerDereferenceSimple) rValue).getPointer());

View File

@ -7,7 +7,7 @@ import dk.camelot64.kickc.parser.KickCParser;
import org.antlr.v4.runtime.tree.TerminalNode;
/** Capable of evaluating constants directly on the parse tree. */
public class ParseTreeConstantEvaluator extends KickCBaseVisitor<Constant> {
public class ParseTreeConstantEvaluator extends KickCBaseVisitor<ConstantValue> {
/**
* Attempt to evaluate a constant expression.
@ -15,12 +15,12 @@ public class ParseTreeConstantEvaluator extends KickCBaseVisitor<Constant> {
* @param expr The expression to evaluate
* @return The constant value of the expression. null if the expression is not constant.
*/
public static Constant evaluate(KickCParser.ExprContext expr) {
public static ConstantValue evaluate(KickCParser.ExprContext expr) {
return (new ParseTreeConstantEvaluator()).visit(expr);
}
@Override
public Constant visitExprNumber(KickCParser.ExprNumberContext ctx) {
public ConstantValue visitExprNumber(KickCParser.ExprNumberContext ctx) {
Number number = NumberParser.parseLiteral(ctx.getText());
if(number instanceof Integer) {
return new ConstantInteger((Integer) number);
@ -30,62 +30,62 @@ public class ParseTreeConstantEvaluator extends KickCBaseVisitor<Constant> {
}
@Override
public Constant visitExprString(KickCParser.ExprStringContext ctx) {
public ConstantValue visitExprString(KickCParser.ExprStringContext ctx) {
return new ConstantString(ctx.getText());
}
@Override
public Constant visitExprBool(KickCParser.ExprBoolContext ctx) {
public ConstantValue visitExprBool(KickCParser.ExprBoolContext ctx) {
return new ConstantBool(Boolean.getBoolean(ctx.getText()));
}
@Override
public Constant visitExprPar(KickCParser.ExprParContext ctx) {
public ConstantValue visitExprPar(KickCParser.ExprParContext ctx) {
return visit(ctx.expr());
}
@Override
public Constant visitExprCast(KickCParser.ExprCastContext ctx) {
public ConstantValue visitExprCast(KickCParser.ExprCastContext ctx) {
return visit(ctx.expr());
}
@Override
public Constant visitExprCall(KickCParser.ExprCallContext ctx) {
public ConstantValue visitExprCall(KickCParser.ExprCallContext ctx) {
throw new NotConstantException();
}
@Override
public Constant visitExprArray(KickCParser.ExprArrayContext ctx) {
public ConstantValue visitExprArray(KickCParser.ExprArrayContext ctx) {
throw new NotConstantException();
}
@Override
public Constant visitExprId(KickCParser.ExprIdContext ctx) {
public ConstantValue visitExprId(KickCParser.ExprIdContext ctx) {
throw new NotConstantException();
}
@Override
public Constant visitInitExpr(KickCParser.InitExprContext ctx) {
public ConstantValue visitInitExpr(KickCParser.InitExprContext ctx) {
return visit(ctx.expr());
}
@Override
public Constant visitInitList(KickCParser.InitListContext ctx) {
public ConstantValue visitInitList(KickCParser.InitListContext ctx) {
throw new NotConstantException();
}
@Override
public Constant visitExprUnary(KickCParser.ExprUnaryContext ctx) {
Constant sub = visit(ctx.expr());
public ConstantValue visitExprUnary(KickCParser.ExprUnaryContext ctx) {
ConstantValue sub = visit(ctx.expr());
String op = ((TerminalNode)ctx.getChild(0)).getSymbol().getText();
Operator operator = Operator.getUnary(op);
return calculateUnary(operator, sub);
}
@Override
public Constant visitExprBinary(KickCParser.ExprBinaryContext ctx) {
Constant left = this.visit(ctx.expr(0));
Constant right = this.visit(ctx.expr(1));
public ConstantValue visitExprBinary(KickCParser.ExprBinaryContext ctx) {
ConstantValue left = this.visit(ctx.expr(0));
ConstantValue right = this.visit(ctx.expr(1));
String op = ((TerminalNode)ctx.getChild(1)).getSymbol().getText();
Operator operator = Operator.getBinary(op);
return calculateBinary(operator, left, right);
@ -97,7 +97,7 @@ public class ParseTreeConstantEvaluator extends KickCBaseVisitor<Constant> {
}
}
static Constant calculateBinary(Operator operator, Constant c1, Constant c2) {
static ConstantValue calculateBinary(Operator operator, ConstantValue c1, ConstantValue c2) {
switch (operator.getOperator()) {
case "-": {
if (c1 instanceof ConstantInteger && c2 instanceof ConstantInteger) {
@ -136,7 +136,7 @@ public class ParseTreeConstantEvaluator extends KickCBaseVisitor<Constant> {
}
}
private static Integer getInteger(Constant constant) {
private static Integer getInteger(ConstantValue constant) {
if (constant instanceof ConstantInteger) {
return ((ConstantInteger) constant).getNumber();
} else {
@ -144,7 +144,7 @@ public class ParseTreeConstantEvaluator extends KickCBaseVisitor<Constant> {
}
}
private static Double getDouble(Constant constant) {
private static Double getDouble(ConstantValue constant) {
if (constant instanceof ConstantDouble) {
return ((ConstantDouble) constant).getNumber();
} else if (constant instanceof ConstantInteger) {
@ -154,7 +154,7 @@ public class ParseTreeConstantEvaluator extends KickCBaseVisitor<Constant> {
}
}
public static Constant calculateUnary(Operator operator, Constant c) {
public static ConstantValue calculateUnary(Operator operator, ConstantValue c) {
switch (operator.getOperator()) {
case "-": {
if (c instanceof ConstantInteger) {

View File

@ -415,7 +415,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
public SymbolType visitTypeArray(KickCParser.TypeArrayContext ctx) {
SymbolType elementType = (SymbolType) visit(ctx.typeDecl());
if(ctx.expr()!=null) {
Constant size = ParseTreeConstantEvaluator.evaluate(ctx.expr());
ConstantValue size = ParseTreeConstantEvaluator.evaluate(ctx.expr());
if (size instanceof ConstantInteger) {
return new SymbolTypeArray(elementType, ((ConstantInteger) size).getNumber());
} else {

View File

@ -33,7 +33,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
this.usages = countVarUsages();
// Examine all assigments - performing constant consolidation
// Examine all assignments - performing constant consolidation
for (ControlFlowBlock block : getGraph().getAllBlocks()) {
for (Statement statement : block.getStatements()) {
if (statement instanceof StatementAssignment) {
@ -60,20 +60,20 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
private boolean optimizePointerDereferenceIndexed(StatementAssignment assignment) {
PointerDereferenceIndexed pointerDereferenceIndexed = (PointerDereferenceIndexed) assignment.getlValue();
if(pointerDereferenceIndexed.getPointer() instanceof Constant && pointerDereferenceIndexed.getIndex() instanceof Constant) {
Constant ptrConstant = (Constant) pointerDereferenceIndexed.getPointer();
Constant idxConstant = (Constant) pointerDereferenceIndexed.getIndex();
Constant newPtr = new ConstantBinary(ptrConstant, Operator.PLUS, idxConstant);
if(pointerDereferenceIndexed.getPointer() instanceof ConstantValue && pointerDereferenceIndexed.getIndex() instanceof ConstantValue) {
ConstantValue ptrConstant = (ConstantValue) pointerDereferenceIndexed.getPointer();
ConstantValue idxConstant = (ConstantValue) pointerDereferenceIndexed.getIndex();
ConstantValue newPtr = new ConstantBinary(ptrConstant, Operator.PLUS, idxConstant);
assignment.setlValue(new PointerDereferenceSimple(newPtr));
getLog().append("Consolidated assigned array index constant in assignment " + assignment.getlValue());
return true;
}
if(pointerDereferenceIndexed.getPointer() instanceof Constant && pointerDereferenceIndexed.getIndex() instanceof VariableRef) {
if(pointerDereferenceIndexed.getPointer() instanceof ConstantValue && pointerDereferenceIndexed.getIndex() instanceof VariableRef) {
VariableRef variable = (VariableRef) pointerDereferenceIndexed.getIndex();
Constant consolidated = consolidateSubConstants(variable);
ConstantValue consolidated = consolidateSubConstants(variable);
if (consolidated != null) {
Constant ptrConstant = (Constant) pointerDereferenceIndexed.getPointer();
Constant newPtr = new ConstantBinary(ptrConstant, Operator.PLUS, consolidated);
ConstantValue ptrConstant = (ConstantValue) pointerDereferenceIndexed.getPointer();
ConstantValue newPtr = new ConstantBinary(ptrConstant, Operator.PLUS, consolidated);
pointerDereferenceIndexed.setPointer(newPtr);
getLog().append("Consolidated assigned array index constant in assignment " + assignment.getlValue());
return true;
@ -83,22 +83,22 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
}
private boolean optimizeArrayDeref(StatementAssignment assignment) {
if (assignment.getrValue1() instanceof Constant && assignment.getrValue2() instanceof Constant) {
Constant ptrConstant = (Constant) assignment.getrValue1();
Constant idxConstant = (Constant) assignment.getrValue2();
Constant newPtr = new ConstantBinary(ptrConstant, Operator.PLUS, idxConstant);
if (assignment.getrValue1() instanceof ConstantValue && assignment.getrValue2() instanceof ConstantValue) {
ConstantValue ptrConstant = (ConstantValue) assignment.getrValue1();
ConstantValue idxConstant = (ConstantValue) assignment.getrValue2();
ConstantValue newPtr = new ConstantBinary(ptrConstant, Operator.PLUS, idxConstant);
assignment.setrValue1(null);
assignment.setOperator(Operator.STAR);
assignment.setrValue2(newPtr);
getLog().append("Consolidated referenced array index constant in assignment " + assignment.getlValue());
return true;
}
if (assignment.getrValue1() instanceof Constant && assignment.getrValue2() instanceof VariableRef) {
if (assignment.getrValue1() instanceof ConstantValue && assignment.getrValue2() instanceof VariableRef) {
VariableRef variable = (VariableRef) assignment.getrValue2();
Constant consolidated = consolidateSubConstants(variable);
ConstantValue consolidated = consolidateSubConstants(variable);
if (consolidated != null) {
Constant ptrConstant = (Constant) assignment.getrValue1();
Constant newPtr = new ConstantBinary(ptrConstant, Operator.PLUS, consolidated);
ConstantValue ptrConstant = (ConstantValue) assignment.getrValue1();
ConstantValue newPtr = new ConstantBinary(ptrConstant, Operator.PLUS, consolidated);
assignment.setrValue1(newPtr);
getLog().append("Consolidated referenced array index constant in assignment " + assignment.getlValue());
return true;
@ -108,21 +108,21 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
}
private boolean optimizePlus(StatementAssignment assignment) {
if (assignment.getrValue1() instanceof Constant && assignment.getrValue2() instanceof VariableRef) {
if (assignment.getrValue1() instanceof ConstantValue && assignment.getrValue2() instanceof VariableRef) {
VariableRef variable = (VariableRef) assignment.getrValue2();
Constant consolidated = consolidateSubConstants(variable);
ConstantValue consolidated = consolidateSubConstants(variable);
if (consolidated != null) {
Constant const1 = (Constant) assignment.getrValue1();
ConstantValue const1 = (ConstantValue) assignment.getrValue1();
assignment.setrValue1(new ConstantBinary(const1, Operator.PLUS, consolidated));
getLog().append("Consolidated constant in assignment " + assignment.getlValue());
return true;
}
} else if (assignment.getrValue1() instanceof VariableRef && assignment.getrValue2() instanceof Constant) {
} else if (assignment.getrValue1() instanceof VariableRef && assignment.getrValue2() instanceof ConstantValue) {
VariableRef variable = (VariableRef) assignment.getrValue1();
Constant consolidated = consolidateSubConstants(variable);
ConstantValue consolidated = consolidateSubConstants(variable);
if (consolidated != null) {
Constant const2 = (Constant) assignment.getrValue2();
Constant newNumber = new ConstantBinary(consolidated, Operator.PLUS, const2);
ConstantValue const2 = (ConstantValue) assignment.getrValue2();
ConstantValue newNumber = new ConstantBinary(consolidated, Operator.PLUS, const2);
assignment.setrValue2(newNumber);
// Handling of negative consolidated numbers?
getLog().append("Consolidated constant in assignment " + assignment.getlValue());
@ -138,34 +138,34 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
* @param variable The variable to examine
* @return The consolidated constant. Null if no sub-constants were found, or if the constants cannot be consolidated.
*/
private Constant consolidateSubConstants(VariableRef variable) {
private ConstantValue consolidateSubConstants(VariableRef variable) {
if(getUsages(variable) >1) {
getLog().append("Multiple usages for variable. Not optimizing sub-constant "+variable.toString(getProgram()));
return null;
}
StatementAssignment assignment = getGraph().getAssignment(variable);
if (assignment != null && assignment.getOperator() != null && "+".equals(assignment.getOperator().getOperator())) {
if (assignment.getrValue1() instanceof Constant) {
Constant constant = (Constant) assignment.getrValue1();
if (assignment.getrValue1() instanceof ConstantValue) {
ConstantValue constant = (ConstantValue) assignment.getrValue1();
assignment.setrValue1(null);
assignment.setOperator(null);
return constant;
} else if (assignment.getrValue2() instanceof Constant) {
Constant constant = (Constant) assignment.getrValue2();
} else if (assignment.getrValue2() instanceof ConstantValue) {
ConstantValue constant = (ConstantValue) assignment.getrValue2();
assignment.setrValue2(assignment.getrValue1());
assignment.setOperator(null);
assignment.setrValue1(null);
return constant;
} else {
Constant const1 = null;
ConstantValue const1 = null;
if (assignment.getrValue1() instanceof VariableRef) {
const1 = consolidateSubConstants((VariableRef) assignment.getrValue1());
}
Constant const2 = null;
ConstantValue const2 = null;
if (assignment.getrValue2() instanceof VariableRef) {
const2 = consolidateSubConstants((VariableRef) assignment.getrValue2());
}
Constant result = null;
ConstantValue result = null;
if (const1 != null) {
result = const1;
if (const2 != null) {
@ -178,26 +178,26 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
}
}
if (assignment != null && assignment.getOperator() != null && "-".equals(assignment.getOperator().getOperator())) {
if (assignment.getrValue1() instanceof Constant) {
Constant constant = (Constant) assignment.getrValue1();
if (assignment.getrValue1() instanceof ConstantValue) {
ConstantValue constant = (ConstantValue) assignment.getrValue1();
assignment.setrValue1(null);
return constant;
} else if (assignment.getrValue2() instanceof Constant) {
Constant constant = (Constant) assignment.getrValue2();
} else if (assignment.getrValue2() instanceof ConstantValue) {
ConstantValue constant = (ConstantValue) assignment.getrValue2();
assignment.setrValue2(assignment.getrValue1());
assignment.setOperator(null);
assignment.setrValue1(null);
return new ConstantUnary(Operator.MINUS, constant);
} else {
Constant const1 = null;
ConstantValue const1 = null;
if (assignment.getrValue1() instanceof VariableRef) {
const1 = consolidateSubConstants((VariableRef) assignment.getrValue1());
}
Constant const2 = null;
ConstantValue const2 = null;
if (assignment.getrValue2() instanceof VariableRef) {
const2 = consolidateSubConstants((VariableRef) assignment.getrValue2());
}
Constant result = null;
ConstantValue result = null;
if (const1 != null) {
result = const1;
if (const2 != null) {

View File

@ -117,7 +117,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
}
static ConstantValue createBinary(Constant c1, Operator operator, Constant c2) {
static ConstantValue createBinary(ConstantValue c1, Operator operator, ConstantValue c2) {
switch (operator.getOperator()) {
case "-":
case "+":
@ -132,7 +132,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
}
}
static ConstantValue createUnary(Operator operator, Constant c) {
static ConstantValue createUnary(Operator operator, ConstantValue c) {
switch (operator.getOperator()) {
case "-":
case "+":

View File

@ -36,7 +36,7 @@ public class Pass3PhiLifting {
StatementPhiBlock phiBlock = block.getPhiBlock();
for (StatementPhiBlock.PhiVariable phiVariable : phiBlock.getPhiVariables()) {
for (StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
if (!(phiRValue.getrValue() instanceof Constant)) {
if (!(phiRValue.getrValue() instanceof ConstantValue)) {
LabelRef predecessorRef = phiRValue.getPredecessor();
ControlFlowBlock predecessorBlock = graph.getBlock(predecessorRef);
VariableRef rValVarRef = (VariableRef) phiRValue.getrValue();

View File

@ -108,7 +108,7 @@ public class Pass3PhiMemCoalesce extends Pass2SsaOptimization {
VariableRef variable = phiVariable.getVariable();
LiveRangeEquivalenceClass equivalenceClass = phiEquivalenceClasses.getOrCreateEquivalenceClass(variable);
for (StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
if (!(phiRValue.getrValue() instanceof Constant)) {
if (!(phiRValue.getrValue() instanceof ConstantValue)) {
VariableRef phiRVar = (VariableRef) phiRValue.getrValue();
LiveRangeEquivalenceClass rValEquivalenceClass = phiEquivalenceClasses.getOrCreateEquivalenceClass(phiRVar);
if(!rValEquivalenceClass.equals(equivalenceClass)) {

View File

@ -50,8 +50,8 @@ public class VariableReplacer {
}
} else if (rValue instanceof ConstantBinary) {
ConstantBinary constantBinary = (ConstantBinary) rValue;
Constant aliasLeft = (Constant) getReplacement(constantBinary.getLeft());
Constant aliasRight = (Constant) getReplacement(constantBinary.getRight());
ConstantValue aliasLeft = (ConstantValue) getReplacement(constantBinary.getLeft());
ConstantValue aliasRight = (ConstantValue) getReplacement(constantBinary.getRight());
if (aliasLeft != null || aliasRight != null) {
if (aliasLeft == null) {
aliasLeft = constantBinary.getLeft();