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

67 lines
2.8 KiB
Java

package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.statements.Statement;
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.values.LValue;
import dk.camelot64.kickc.model.values.ProcedureRef;
import dk.camelot64.kickc.model.values.VariableRef;
import java.util.Collection;
/** Remove temporary variables assigned any void return value */
public class Pass1CallVoidReturns extends Pass2SsaOptimization {
public Pass1CallVoidReturns(Program program) {
super(program);
}
@Override
public boolean step() {
new PassNStatementIndices(getProgram()).execute();
getProgram().clearVariableReferenceInfos();
getProgram().clearControlFlowBlockSuccessorClosure();
VariableReferenceInfos referenceInfos = getProgram().getVariableReferenceInfos();
for(var statement : getGraph().getAllStatements()) {
if (statement instanceof StatementCall) {
final ProcedureRef procedureRef = ((StatementCall) statement).getProcedure();
final Procedure procedure = getProgramScope().getProcedure(procedureRef);
if (SymbolType.VOID.equals(procedure.getReturnType())) {
// Found a call to a VOID returning procedure
final LValue lValue = ((StatementCall) statement).getlValue();
if (lValue instanceof VariableRef) {
VariableRef tmpVar = (VariableRef) lValue;
final Collection<Integer> usages = referenceInfos.getVarUseStatements(tmpVar);
if (usages.size() > 0) {
final Integer usageIdx = usages.iterator().next();
final Statement usage = getProgram().getStatementInfos()
.getStatement(usageIdx);
throw new CompileError(
"Function " + procedure.getLocalName() + " does not return a value! ",
usage);
} else {
// Delete the temporary variable
final Variable var = getProgramScope().getVar(tmpVar);
var.getScope().remove(var);
// And remove the lValue
((StatementCall) statement).setlValue(null);
if (getLog().isVerbosePass1CreateSsa()) {
getLog().append("Removing LValue from call to function returning void");
}
}
}
}
}
}
getProgram().clearStatementIndices();
getProgram().clearVariableReferenceInfos();
getProgram().clearControlFlowBlockSuccessorClosure();
return false;
}
}