1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-10 10:29:36 +00:00
kickc/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructPrepare.java
2023-04-10 11:19:32 +02:00

68 lines
2.9 KiB
Java

package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.Initializers;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.statements.StatementCall;
import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeInference;
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
import dk.camelot64.kickc.model.values.CastValue;
import dk.camelot64.kickc.model.values.ConstantValue;
import dk.camelot64.kickc.model.values.RValue;
import dk.camelot64.kickc.model.values.ValueList;
import java.util.List;
/**
* Prepare structs for unwinding.
* - Constantify all assignment RValues that are structs
* - Add casts to struct parameter values in calls
*/
public class Pass1UnwindStructPrepare extends Pass2SsaOptimization {
public Pass1UnwindStructPrepare(Program program) {
super(program);
}
@Override
public boolean step() {
for(var statement : getGraph().getAllStatements()) {
if(statement instanceof StatementAssignment assignment) {
if(assignment.getOperator()==null) {
SymbolType lValueType = SymbolTypeInference.inferType(getProgram().getScope(), assignment.getlValue());
RValue rValue = assignment.getrValue2();
if(!(rValue instanceof ConstantValue) && lValueType instanceof SymbolTypeStruct) {
// TODO: Constantify all R-Values?
Initializers.ValueTypeSpec lValueTypeSpec = new Initializers.ValueTypeSpec(lValueType);
RValue rValueConstantified = Initializers.constantify(rValue, lValueTypeSpec, getProgram(), assignment.getSource());
if(!rValue.equals(rValueConstantified)) {
assignment.setrValue2(rValueConstantified);
getLog().append("Constantified RValue "+assignment.toString(getProgram(), false));
}
}
}
}
if(statement instanceof final StatementCall call) {
final Procedure procedure = getProgramScope().getProcedure(call.getProcedure());
final List<Variable> paramDefs = procedure.getParameters();
final List<RValue> paramVals = call.getParameters();
for(int i=0;i<paramDefs.size();i++) {
final Variable paramDef = paramDefs.get(i);
final RValue paramVal = paramVals.get(i);
if(paramDef.getType() instanceof SymbolTypeStruct && paramVal instanceof ValueList) {
// Add a cast to the parameter value list
paramVals.set(i, new CastValue(paramDef.getType(), paramVal));
getLog().append("Added struct type cast to parameter value list "+call.toString(getProgram(), false));
}
}
}
}
return false;
}
}