1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-04-07 06:37:31 +00:00

Removed two passes that are no longer needed.

This commit is contained in:
jespergravgaard 2019-11-23 19:15:31 +01:00
parent 4d9c23b6bc
commit 7b71a62924
5 changed files with 162 additions and 254 deletions

@ -277,7 +277,6 @@ public class Compiler {
List<PassStep> optimizations = new ArrayList<>();
optimizations.add(new Pass2FixInlineConstructors(program));
optimizations.add(new PassNAddNumberTypeConversions(program));
optimizations.add(new PassNAddInitializerValueListTypeCasts(program));
optimizations.add(new Pass2InlineCast(program));
optimizations.add(new PassNCastSimplification(program));
optimizations.add(new PassNFinalizeNumberTypeConversions(program));
@ -302,7 +301,6 @@ public class Compiler {
optimizations.add(new PassNArrayElementAddressOfRewriting(program));
optimizations.add(new Pass2ConditionalJumpSequenceImprovement(program));
optimizations.add(new Pass2ConstantRValueConsolidation(program));
optimizations.add(new Pass2ConstantInitializerValueLists(program));
optimizations.add(new Pass2ConstantIdentification(program));
optimizations.add(new Pass2ConstantValues(program));
optimizations.add(new Pass2ConstantCallPointerIdentification(program));

@ -0,0 +1,160 @@
package dk.camelot64.kickc.model;
import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.statements.StatementSource;
import dk.camelot64.kickc.model.symbols.StructDefinition;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.*;
import dk.camelot64.kickc.model.values.*;
import java.util.*;
/** Utility methods for finding constant struct/array values from {@link dk.camelot64.kickc.model.values.ValueList}. */
public class ConstantValueLists {
/**
* Add cast to a value inside a value list initializer based on the declared type of the symbol.
*
* @param declaredType The declared type of the value
* @param isArray true if the declared variable is an array
* @param programValue The value wrapped in a program value
* @param source The current statement
* @return true if anything was modified
*/
public static boolean addValueCasts(SymbolType declaredType, boolean isArray, ProgramValue programValue, Program program, StatementSource source) {
boolean exprModified = false;
Value value = programValue.get();
if(value instanceof ValueList) {
ValueList valueList = (ValueList) value;
if(declaredType instanceof SymbolTypePointer && isArray) {
SymbolTypePointer declaredArrayType = (SymbolTypePointer) declaredType;
// Recursively cast all sub-elements
SymbolType declaredElmType = declaredArrayType.getElementType();
int size = valueList.getList().size();
// TODO: Check declared array size vs. actual size
for(int i = 0; i < size; i++) {
exprModified |= addValueCasts(declaredElmType, false, new ProgramValue.ProgramValueListElement(valueList, i), program, source);
}
// Add a cast to the value list itself
programValue.set(new CastValue(declaredType, valueList));
} else if(declaredType instanceof SymbolTypeStruct) {
SymbolTypeStruct declaredStructType = (SymbolTypeStruct) declaredType;
// Recursively cast all sub-elements
StructDefinition structDefinition = declaredStructType.getStructDefinition(program.getScope());
Collection<Variable> memberDefinitions = structDefinition.getAllVars(false);
int size = memberDefinitions.size();
if(size != valueList.getList().size()) {
throw new CompileError(
"Struct initializer has wrong size (" + valueList.getList().size() + "), " +
"which does not match the number of members in " + declaredStructType.getTypeName() + " (" + size + " members).\n" +
" Struct initializer: " + valueList.toString(program),
source);
}
Iterator<Variable> memberDefIt = memberDefinitions.iterator();
for(int i = 0; i < size; i++) {
Variable memberDef = memberDefIt.next();
exprModified |= addValueCasts(memberDef.getType(), memberDef.isArray(), new ProgramValue.ProgramValueListElement(valueList, i), program, source);
}
// Add a cast to the value list itself
programValue.set(new CastValue(declaredType, valueList));
} else {
// TODO: Handle word/dword initializers
throw new InternalError("Type not handled! " + declaredType);
}
} else {
SymbolType valueType = SymbolTypeInference.inferType(program.getScope(), (RValue) value);
if(SymbolType.NUMBER.equals(valueType) || SymbolType.VAR.equals(valueType)) {
// Check if the value fits.
if(!SymbolTypeConversion.assignmentTypeMatch(declaredType, valueType)) {
throw new CompileError("Declared type " + declaredType + " does not match element type " + valueType, source);
}
// TODO: Test if the value matches the declared type!
// Add a cast to the value
if(value instanceof ConstantValue) {
programValue.set(new ConstantCastValue(declaredType, (ConstantValue) value));
} else {
programValue.set(new CastValue(declaredType, (RValue) value));
}
exprModified = true;
}
}
return exprModified;
}
/**
* Convert a value list (with casts) to a constant value of the declared type - if all sub-values are constant. Otherwise returns null.
*
* @param declaredType The type of the lvalue
* @param valueList The list of values
* @return The constant value if all list elements are constant. null if elements are not constant
*/
public static ConstantValue getConstantValue(SymbolType declaredType, ValueList valueList, Program program, StatementSource source) {
// Examine whether all list elements are constant
List<RValue> values = valueList.getList();
List<ConstantValue> constantValues = new ArrayList<>();
for(RValue elmValue : values) {
if(elmValue instanceof ConstantValue) {
ConstantValue constantValue = (ConstantValue) elmValue;
constantValues.add(constantValue);
} else if(elmValue instanceof CastValue) {
// Recursion may be needed
CastValue castValue = (CastValue) elmValue;
if(castValue.getValue() instanceof ValueList) {
ConstantValue constantValue = getConstantValue(castValue.getToType(), (ValueList) castValue.getValue(), program, source);
if(constantValue != null) {
constantValues.add(constantValue);
} else {
// A non-constant was found - exit
return null;
}
} else {
// A non-constant was found - exit
return null;
}
} else {
// A non-constant was found - exit
return null;
}
}
// All elements are constant - convert to constant of declared type
if(declaredType instanceof SymbolTypePointer) {
// Check that type of constant values match the array element type
SymbolType declaredElementType = ((SymbolTypePointer) declaredType).getElementType();
for(ConstantValue constantValue : constantValues) {
SymbolType elmType = constantValue.getType(program.getScope());
if(!elmType.equals(declaredElementType)) {
throw new CompileError("Initializer element " + constantValue.toString(program) + " does not match array type " + declaredType.getTypeName(), source);
}
}
// Return the constant array
return new ConstantArrayList(constantValues, declaredElementType);
} else if(declaredType instanceof SymbolTypeStruct) {
// Check that type of constant values match the struct member types
SymbolTypeStruct declaredStructType = (SymbolTypeStruct) declaredType;
StructDefinition structDefinition = declaredStructType.getStructDefinition(program.getScope());
Collection<Variable> memberDefs = structDefinition.getAllVars(false);
if(memberDefs.size() != constantValues.size()) {
throw new CompileError(
"Struct initializer has wrong size (" + valueList.getList().size() + "), " +
"which does not match the number of members in " + declaredStructType.getTypeName() + " (\"+size+\" members).\n" +
" Struct initializer: " + valueList.toString(program),
source);
}
Iterator<Variable> memberDefIt = memberDefs.iterator();
LinkedHashMap<SymbolVariableRef, ConstantValue> memberValues = new LinkedHashMap<>();
for(int i = 0; i < constantValues.size(); i++) {
Variable memberDef = memberDefIt.next();
SymbolType declaredElementType = memberDef.getType();
ConstantValue memberValue = constantValues.get(i);
SymbolType elmType = memberValue.getType(program.getScope());
if(!SymbolTypeConversion.assignmentTypeMatch(declaredElementType, elmType)) {
throw new CompileError("Initializer element " + memberValue.toString(program) + " does not match struct member type " + memberDef.toString(program), source);
}
memberValues.put(memberDef.getRef(), memberValue);
}
return new ConstantStructValue(declaredStructType, memberValues);
} else {
throw new InternalError("Not supported " + declaredType);
}
}
}

@ -659,12 +659,12 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
// Convert initializer value lists to constant if possible
if((initValue instanceof ValueList)) {
ProgramValue programValue = new ProgramValue.GenericValue(initValue);
PassNAddInitializerValueListTypeCasts.addValueCasts(type, declIsArray, programValue, program, statementSource);
ConstantValueLists.addValueCasts(type, declIsArray, programValue, program, statementSource);
if(programValue.get() instanceof CastValue) {
CastValue castValue = (CastValue) programValue.get();
if(castValue.getValue() instanceof ValueList) {
// Found value list with cast - look through all elements
ConstantValue constantValue = Pass2ConstantInitializerValueLists.getConstantValueFromList(castValue.getToType(), (ValueList) castValue.getValue(), program, statementSource);
ConstantValue constantValue = ConstantValueLists.getConstantValue(castValue.getToType(), (ValueList) castValue.getValue(), program, statementSource);
if(constantValue != null) {
// Converted value list to constant!!
initValue = constantValue;

@ -1,127 +0,0 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.InternalError;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.statements.StatementSource;
import dk.camelot64.kickc.model.symbols.StructDefinition;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.*;
import dk.camelot64.kickc.model.values.*;
import java.util.*;
/**
* Compiler Pass identifying typed (through a cast) initializer value lists with constant values and converting them into struct/array/number {@link ConstantValue}s
*/
public class Pass2ConstantInitializerValueLists extends Pass2SsaOptimization {
public Pass2ConstantInitializerValueLists(Program program) {
super(program);
}
/**
* Look for value lists with casts that have all-constant values. Convert to the proper {@link ConstantValue}s
*
* @return true optimization was performed. false if no optimization was possible.
*/
@Override
public boolean step() {
final boolean[] modified = {false};
ProgramValueIterator.execute(getGraph(), (programValue, currentStmt, stmtIt, currentBlock) -> {
if(programValue.get() instanceof CastValue) {
CastValue castValue = (CastValue) programValue.get();
if(castValue.getValue() instanceof ValueList) {
// Found value list with cast - look through all elements
ConstantValue constantValue = getConstantValueFromList(castValue.getToType(), (ValueList) castValue.getValue(), getProgram(), currentStmt.getSource());
if(constantValue!=null) {
programValue.set(constantValue);
getLog().append("Identified constant from value list ("+castValue.getToType()+") "+constantValue.toString(getProgram()));
modified[0] = true;
}
}
}
});
return modified[0];
}
/**
* Examine a value list to determine if all elements are constants.
* If they are - convert the value list to a constant value of the declared type
*
* @param declaredType The type of the lvalue
* @param valueList The list of values
* @return The constant value if all list elements are constant. null if elements are not constant
*/
public static ConstantValue getConstantValueFromList(SymbolType declaredType, ValueList valueList, Program program, StatementSource source) {
// Examine whether all list elements are constant
List<RValue> values = valueList.getList();
List<ConstantValue> constantValues = new ArrayList<>();
for(RValue elmValue : values) {
if(elmValue instanceof ConstantValue) {
ConstantValue constantValue = (ConstantValue) elmValue;
constantValues.add(constantValue);
} else if(elmValue instanceof CastValue) {
// Recursion may be needed
CastValue castValue = (CastValue) elmValue;
if(castValue.getValue() instanceof ValueList) {
ConstantValue constantValue = getConstantValueFromList(castValue.getToType(), (ValueList) castValue.getValue(), program, source);
if(constantValue!=null) {
constantValues.add(constantValue);
} else {
// A non-constant was found - exit
return null;
}
} else {
// A non-constant was found - exit
return null;
}
} else {
// A non-constant was found - exit
return null;
}
}
// All elements are constant - convert to constant of declared type
if(declaredType instanceof SymbolTypePointer) {
// Check that type of constant values match the array element type
SymbolType declaredElementType = ((SymbolTypePointer) declaredType).getElementType();
for(ConstantValue constantValue : constantValues) {
SymbolType elmType = constantValue.getType(program.getScope());
if(!elmType.equals(declaredElementType)) {
throw new CompileError("Initializer element "+constantValue.toString(program)+" does not match array type "+declaredType.getTypeName(), source);
}
}
// Return the constant array
return new ConstantArrayList(constantValues, declaredElementType);
} else if(declaredType instanceof SymbolTypeStruct) {
// Check that type of constant values match the struct member types
SymbolTypeStruct declaredStructType = (SymbolTypeStruct) declaredType;
StructDefinition structDefinition = declaredStructType.getStructDefinition(program.getScope());
Collection<Variable> memberDefs = structDefinition.getAllVars(false);
if(memberDefs.size()!=constantValues.size()) {
throw new CompileError(
"Struct initializer has wrong size ("+valueList.getList().size()+"), " +
"which does not match the number of members in "+declaredStructType.getTypeName()+" (\"+size+\" members).\n" +
" Struct initializer: "+valueList.toString(program),
source);
}
Iterator<Variable> memberDefIt = memberDefs.iterator();
LinkedHashMap<SymbolVariableRef, ConstantValue> memberValues = new LinkedHashMap<>();
for(int i = 0; i < constantValues.size(); i++) {
Variable memberDef = memberDefIt.next();
SymbolType declaredElementType = memberDef.getType();
ConstantValue memberValue = constantValues.get(i);
SymbolType elmType = memberValue.getType(program.getScope());
if(!SymbolTypeConversion.assignmentTypeMatch(declaredElementType, elmType)) {
throw new CompileError("Initializer element "+ memberValue.toString(program)+" does not match struct member type "+memberDef.toString(program), source);
}
memberValues.put(memberDef.getRef(), memberValue);
}
return new ConstantStructValue(declaredStructType, memberValues);
} else {
throw new InternalError("Not supported "+declaredType);
}
}
}

@ -1,123 +0,0 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.InternalError;
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.iterator.ProgramValue;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.StatementSource;
import dk.camelot64.kickc.model.symbols.StructDefinition;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.*;
import dk.camelot64.kickc.model.values.*;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Add casts to all expressions that are inside value list initializers <code><{ ... }/code> based on the type of the array/struct
*/
public class PassNAddInitializerValueListTypeCasts extends Pass2SsaOptimization {
public PassNAddInitializerValueListTypeCasts(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;
if(binary.getRight() instanceof ValueList && binary.getOperator().equals(Operators.ASSIGNMENT)) {
RValue left = binary.getLeft();
SymbolType declaredType = SymbolTypeInference.inferType(getProgram().getScope(), left);
boolean isArray = false;
if(left instanceof SymbolVariableRef) {
Variable constant = getScope().getVar((SymbolVariableRef) left);
isArray = constant.isArray();
}
boolean isModified = addValueCasts(declaredType, isArray, binary.getRightValue(), getProgram(), currentStmt.getSource());
if(isModified) {
getLog().append("Added casts to value list in " + currentStmt.toString(getProgram(), false));
modified.set(true);
}
}
}
});
return modified.get();
}
/**
* Add cast to a value inside a value list initializer.
*
* @param declaredType The declared type of the value
* @param isArray true if the declared variable is an array
* @param programValue The value wrapped in a program value
* @param source The current statement
* @return true if anything was modified
*/
public static boolean addValueCasts(SymbolType declaredType, boolean isArray, ProgramValue programValue, Program program, StatementSource source) {
boolean exprModified = false;
Value value = programValue.get();
if(value instanceof ValueList) {
ValueList valueList = (ValueList) value;
if(declaredType instanceof SymbolTypePointer && isArray) {
SymbolTypePointer declaredArrayType = (SymbolTypePointer) declaredType;
// Recursively cast all sub-elements
SymbolType declaredElmType = declaredArrayType.getElementType();
int size = valueList.getList().size();
// TODO: Check declared array size vs. actual size
for(int i = 0; i < size; i++) {
exprModified |= addValueCasts(declaredElmType, false, new ProgramValue.ProgramValueListElement(valueList, i), program, source);
}
// Add a cast to the value list itself
programValue.set(new CastValue(declaredType, valueList));
} else if(declaredType instanceof SymbolTypeStruct) {
SymbolTypeStruct declaredStructType = (SymbolTypeStruct) declaredType;
// Recursively cast all sub-elements
StructDefinition structDefinition = declaredStructType.getStructDefinition(program.getScope());
Collection<Variable> memberDefinitions = structDefinition.getAllVars(false);
int size = memberDefinitions.size();
if(size!=valueList.getList().size()) {
throw new CompileError(
"Struct initializer has wrong size ("+valueList.getList().size()+"), " +
"which does not match the number of members in "+declaredStructType.getTypeName()+" ("+size+" members).\n" +
" Struct initializer: "+valueList.toString(program),
source);
}
Iterator<Variable> memberDefIt = memberDefinitions.iterator();
for(int i = 0; i < size; i++) {
Variable memberDef = memberDefIt.next();
exprModified |= addValueCasts(memberDef.getType(), memberDef.isArray(), new ProgramValue.ProgramValueListElement(valueList, i), program, source);
}
// Add a cast to the value list itself
programValue.set(new CastValue(declaredType, valueList));
} else {
// TODO: Handle word/dword initializers
throw new InternalError("Type not handled! "+declaredType);
}
} else {
SymbolType valueType = SymbolTypeInference.inferType(program.getScope(), (RValue) value);
if(SymbolType.NUMBER.equals(valueType) || SymbolType.VAR.equals(valueType)) {
// Check if the value fits.
if(!SymbolTypeConversion.assignmentTypeMatch(declaredType, valueType)) {
throw new CompileError("Declared type " + declaredType + " does not match element type " + valueType, source);
}
// TODO: Test if the value matches the declared type!
// Add a cast to the value
if(value instanceof ConstantValue) {
programValue.set(new ConstantCastValue(declaredType, (ConstantValue) value));
} else {
programValue.set(new CastValue(declaredType, (RValue) value));
}
exprModified = true;
}
}
return exprModified;
}
}