diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeConversion.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeConversion.java index 15c35ad73..9e136c58b 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeConversion.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeConversion.java @@ -27,6 +27,7 @@ public class SymbolTypeConversion { * @return The type resulting from a binary operator performed on the two parameters */ public static SymbolType convertedMathType(SymbolTypeInteger type1, SymbolTypeInteger type2) { + // If any of the two types are unresolved - return an unresolved result if(SymbolType.NUMBER.equals(type1) || SymbolType.NUMBER.equals(type2)) { return SymbolType.NUMBER; } @@ -57,7 +58,7 @@ public class SymbolTypeConversion { } /** - * Find the integer type that results from a binary operator according to the special number type conversion https://gitlab.com/camelot/kickc/issues/181 + * Find the integer type that a number operand in a binary operator should be converted/cast to according to number type conversion https://gitlab.com/camelot/kickc/issues/181 * * @param left The left value * @param right The right value @@ -65,7 +66,7 @@ public class SymbolTypeConversion { * @param currentStmt The current statement (used only for exception context) * @return a non-null fixed integer type if a number type conversion is relevant. */ - public static SymbolType convertedNumberType(RValue left, RValue right, ProgramScope symbols, Statement currentStmt) { + public static SymbolType getNumberCastType(RValue left, RValue right, ProgramScope symbols, Statement currentStmt) { SymbolType leftType = SymbolTypeInference.inferType(symbols, left); SymbolType rightType = SymbolTypeInference.inferType(symbols, right); @@ -80,6 +81,10 @@ public class SymbolTypeConversion { return null; } + // Treat pointers like WORD + if(leftType instanceof SymbolTypePointer) leftType = SymbolType.WORD; + if(rightType instanceof SymbolTypePointer) rightType = SymbolType.WORD; + RValue numberVal; SymbolTypeIntegerFixed fixedType; if(SymbolType.NUMBER.equals(leftType) && SymbolType.isInteger(rightType)) { @@ -125,7 +130,8 @@ public class SymbolTypeConversion { } else { smallestUnsignedType = SymbolTypeIntegerFixed.getSmallestUnsigned(value); } - return smallestUnsignedType.getBits() > fixedType.getBits() ? smallestUnsignedType : fixedType; + return smallestUnsignedType; + //return smallestUnsignedType.getBits() > fixedType.getBits() ? smallestUnsignedType : fixedType; } } else { throw new InternalError("Non-number constant has type number " + right.toString(), currentStmt); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantSimplification.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantSimplification.java index 8b748d28e..cb4490626 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantSimplification.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantSimplification.java @@ -29,13 +29,13 @@ public class Pass2ConstantSimplification extends Pass2SsaOptimization { // Found a candidate!! ConstantInteger intOperand = (ConstantInteger) unary.getOperand(); getLog().append("Simplifying constant integer increment "+unary); - programValue.set(new ConstantInteger(intOperand.getValue()+1)); + programValue.set(new ConstantInteger(intOperand.getValue()+1, intOperand.getType())); optimized[0] = true; } else if(Operators.DECREMENT.equals(unary.getOperator()) && unary.getOperand() instanceof ConstantInteger) { // Found a candidate!! ConstantInteger intOperand = (ConstantInteger) unary.getOperand(); getLog().append("Simplifying constant integer decrement "+unary); - programValue.set(new ConstantInteger(intOperand.getValue()+1)); + programValue.set(new ConstantInteger(intOperand.getValue()-1, intOperand.getType())); optimized[0] = true; } } else if(programValue.get() instanceof ConstantBinary) { @@ -43,10 +43,10 @@ public class Pass2ConstantSimplification extends Pass2SsaOptimization { if(Operators.MULTIPLY.equals(binary.getOperator())) { if(binary.getLeft() instanceof ConstantInteger && ((ConstantInteger) binary.getLeft()).getValue() == 0) { getLog().append("Simplifying constant multiply by zero " + binary); - programValue.set(new ConstantInteger(0L)); + programValue.set(new ConstantInteger(0L, binary.getType(getScope()))); } else if(binary.getRight() instanceof ConstantInteger && ((ConstantInteger) binary.getRight()).getValue() == 0) { getLog().append("Simplifying constant multiply by zero " + binary); - programValue.set(new ConstantInteger(0L)); + programValue.set(new ConstantInteger(0L, binary.getType(getScope()))); } } else if(Operators.PLUS.equals(binary.getOperator())) { if(binary.getLeft() instanceof ConstantInteger && ((ConstantInteger) binary.getLeft()).getValue() == 0) { diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNAddNumberTypeConversions.java b/src/main/java/dk/camelot64/kickc/passes/PassNAddNumberTypeConversions.java index 6854e09b0..7a69f1fd4 100644 --- a/src/main/java/dk/camelot64/kickc/passes/PassNAddNumberTypeConversions.java +++ b/src/main/java/dk/camelot64/kickc/passes/PassNAddNumberTypeConversions.java @@ -6,9 +6,10 @@ import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolTypeConversion; import dk.camelot64.kickc.model.types.SymbolTypeInference; -import dk.camelot64.kickc.model.types.SymbolTypePointer; import dk.camelot64.kickc.model.values.RValue; +import java.util.concurrent.atomic.AtomicBoolean; + /** * Add casts to {@link SymbolType#NUMBER} expressions that meet a typed value in a binary expression (including assignment) */ @@ -20,28 +21,31 @@ public class PassNAddNumberTypeConversions extends Pass2SsaOptimization { @Override public boolean step() { + AtomicBoolean modified = new AtomicBoolean(false); ProgramExpressionIterator.execute(getProgram(), (binaryExpression, currentStmt, stmtIt, currentBlock) -> { if(binaryExpression instanceof ProgramExpressionBinary) { ProgramExpressionBinary binary = (ProgramExpressionBinary) binaryExpression; RValue left = binary.getLeft(); RValue right = binary.getRight(); - SymbolType conversionType = SymbolTypeConversion.convertedNumberType(left, right, getScope(), currentStmt); - if(conversionType != null) { + SymbolType castType = SymbolTypeConversion.getNumberCastType(left, right, getScope(), currentStmt); + if(castType != null) { // Convert both left and right to the found type SymbolType leftType = SymbolTypeInference.inferType(getProgram().getScope(), left); - if(!leftType.equals(conversionType) && !(leftType instanceof SymbolTypePointer)) { - getLog().append("Adding number conversion cast (" + conversionType + ") " + binary.getLeft().toString() + " in " + (currentStmt==null?"":currentStmt.toString(getProgram(), false))); - binary.addLeftCast(conversionType, stmtIt, currentBlock==null?null:currentBlock.getScope(), getScope()); + if(SymbolType.NUMBER.equals(leftType)) { + getLog().append("Adding number conversion cast (" + castType + ") " + binary.getLeft().toString() + " in " + (currentStmt==null?"":currentStmt.toString(getProgram(), false))); + binary.addLeftCast(castType, stmtIt, currentBlock==null?null:currentBlock.getScope(), getScope()); + modified.set(true); } SymbolType rightType = SymbolTypeInference.inferType(getProgram().getScope(), right); - if(!rightType.equals(conversionType) && !(rightType instanceof SymbolTypePointer)) { - getLog().append("Adding number conversion cast (" + conversionType + ") " + binary.getRight().toString() + " in " + ((currentStmt==null)?"":currentStmt.toString(getProgram(), false))); - binary.addRightCast(conversionType, stmtIt, currentBlock==null?null:currentBlock.getScope(), getScope()); + if(rightType.equals(SymbolType.NUMBER)) { + getLog().append("Adding number conversion cast (" + castType + ") " + binary.getRight().toString() + " in " + ((currentStmt==null)?"":currentStmt.toString(getProgram(), false))); + binary.addRightCast(castType, stmtIt, currentBlock==null?null:currentBlock.getScope(), getScope()); + modified.set(true); } } } }); - return false; + return modified.get(); } } diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNAddTypeConversionsNew.java b/src/main/java/dk/camelot64/kickc/passes/PassNAddTypeConversionsNew.java index 4f4e3d1b6..ee10bd5c5 100644 --- a/src/main/java/dk/camelot64/kickc/passes/PassNAddTypeConversionsNew.java +++ b/src/main/java/dk/camelot64/kickc/passes/PassNAddTypeConversionsNew.java @@ -32,6 +32,7 @@ public class PassNAddTypeConversionsNew extends Pass2SsaOptimization { binary.addRightCast(leftType, stmtIt, currentBlock.getScope(), getScope()); } + /* if(SymbolType.isInteger(leftType) && SymbolType.isInteger(rightType)) { SymbolType conversionType = SymbolTypeConversion.convertedMathType((SymbolTypeInteger) leftType, (SymbolTypeInteger) rightType); if(conversionType != null && !SymbolType.NUMBER.equals(conversionType)) { @@ -54,6 +55,7 @@ public class PassNAddTypeConversionsNew extends Pass2SsaOptimization { } } } + */ } }); return false;