mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-17 10:30:43 +00:00
Working on special word+byte downgrade. - down to 190/351.
This commit is contained in:
parent
ea990b5e87
commit
f6f25e728b
@ -233,6 +233,7 @@ public class Compiler {
|
||||
List<Pass2SsaOptimization> optimizations = new ArrayList<>();
|
||||
optimizations.add(new PassNAddTypeConversionsNew(program));
|
||||
optimizations.add(new PassNAddNumberTypeConversions(program));
|
||||
optimizations.add(new PassNDowngradeBytePlusWord(program));
|
||||
optimizations.add(new PassNTypeInference(program));
|
||||
optimizations.add(new PassNTypeIdSimplification(program));
|
||||
optimizations.add(new Pass2CullEmptyBlocks(program));
|
||||
|
@ -35,6 +35,14 @@ public class PassNAddTypeConversionsNew extends Pass2SsaOptimization {
|
||||
if(SymbolType.isInteger(leftType) && SymbolType.isInteger(rightType)) {
|
||||
SymbolType conversionType = SymbolTypeConversion.convertedMathType((SymbolTypeInteger) leftType, (SymbolTypeInteger) rightType);
|
||||
if(conversionType != null && !SymbolType.NUMBER.equals(conversionType)) {
|
||||
// If byte-like + word-like - skip!!
|
||||
if(leftType.equals(SymbolType.WORD) && rightType.equals(SymbolType.BYTE)) {
|
||||
return;
|
||||
}
|
||||
if(rightType.equals(SymbolType.WORD) && leftType.equals(SymbolType.BYTE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert both left and right to the found type
|
||||
if(!leftType.equals(conversionType)) {
|
||||
getLog().append("Adding type conversion cast (" + conversionType + ") " + binary.getLeft().toString() + " in " + currentStmt.toString(getProgram(), false));
|
||||
|
@ -0,0 +1,91 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramExpressionBinary;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Downgrade any number expression cast that are part of a WORD+NUMBER expression to BYTE if the number is small enough to fit in the byte.
|
||||
*/
|
||||
public class PassNDowngradeBytePlusWord extends Pass2SsaOptimization {
|
||||
|
||||
public PassNDowngradeBytePlusWord(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
@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();
|
||||
if(isConstantWord(left) && isWordLike(right) && isByteLike((ConstantValue) left)) {
|
||||
getLog().append("Downgrading number conversion cast to (byte) " + binary.getLeft().toString() + " in " + (currentStmt == null ? "" : currentStmt.toString(getProgram(), false)));
|
||||
binary.addLeftCast(SymbolType.BYTE, stmtIt, currentBlock == null ? null : currentBlock.getScope(), getScope());
|
||||
modified.set(true);
|
||||
} else if(isConstantWord(right) && isWordLike(left) && isByteLike((ConstantValue) right)) {
|
||||
getLog().append("Downgrading number conversion cast to (byte) " + binary.getRight().toString() + " in " + (currentStmt == null ? "" : currentStmt.toString(getProgram(), false)));
|
||||
binary.addRightCast(SymbolType.BYTE, stmtIt, currentBlock == null ? null : currentBlock.getScope(), getScope());
|
||||
modified.set(true);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
return modified.get();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines if a constant value is a byte-like value (can be represented inside a BYTE)
|
||||
*
|
||||
* @param constantValue The value to examine
|
||||
* @return true if the value is a byte-like value
|
||||
*/
|
||||
public boolean isByteLike(ConstantValue constantValue) {
|
||||
ConstantLiteral constantLiteral = (constantValue).calculateLiteral(getScope());
|
||||
if(constantLiteral instanceof ConstantInteger) {
|
||||
ConstantInteger constantInteger = (ConstantInteger) constantLiteral;
|
||||
Long value = constantInteger.getValue();
|
||||
if(SymbolType.BYTE.contains(value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a value is a word-like value (WORD or Pointer)
|
||||
*
|
||||
* @param rValue The value to examine
|
||||
* @return true if the value is a word-like value
|
||||
*/
|
||||
public boolean isWordLike(RValue rValue) {
|
||||
SymbolType symbolType = SymbolTypeInference.inferType(getProgram().getScope(), rValue);
|
||||
return symbolType.equals(SymbolType.WORD) || symbolType instanceof SymbolTypePointer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the passed value is a constant cast to WORD
|
||||
*
|
||||
* @param rValue The value to examine
|
||||
* @return true if the value is a constant cast to word
|
||||
*/
|
||||
public boolean isConstantWord(RValue rValue) {
|
||||
if(rValue instanceof ConstantInteger && ((ConstantInteger) rValue).getType().equals(SymbolType.WORD)) {
|
||||
return true;
|
||||
}
|
||||
if((rValue instanceof ConstantCastValue) && ((ConstantCastValue) rValue).getToType().equals(SymbolType.WORD))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user