1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-26 19:30:00 +00:00

Added ParamValue RValue for retrieving parameter values in procedures. #316

This commit is contained in:
jespergravgaard 2019-09-18 22:41:46 +02:00
parent 70435aec30
commit 6e767862e8
10 changed files with 106 additions and 14 deletions

View File

@ -4,6 +4,7 @@ import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementCall;
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.symbols.Symbol;
import dk.camelot64.kickc.model.values.LabelRef;
import dk.camelot64.kickc.model.values.ScopeRef;
@ -161,8 +162,18 @@ public class ControlFlowBlock implements Serializable {
public String toString(Program program) {
ControlFlowGraph graph = program.getGraph();
StringBuffer out = new StringBuffer();
// TODO: Print signature for procedures (requires updating all tests data)
/*
if(isProcedureEntry(program)) {
Procedure procedure = (Procedure) program.getScope().getScope(scope);
out.append("\n");
out.append(procedure.toString(program)+"\n");
}
*/
out.append(label.getFullName() + ":");
out.append(" scope:[" + scope.getFullName() + "] ");
out.append(" scope:[" + this.scope.getFullName() + "] ");
out.append(" from");
if(graph != null) {
List<ControlFlowBlock> predecessors = graph.getPredecessors(this);

View File

@ -755,8 +755,28 @@ public interface ProgramValue {
}
/** Value inside a parameter value . */
class ProgramValueParamValue implements ProgramValue {
private final ParamValue paramValue;
ProgramValueParamValue(ParamValue paramValue) {
this.paramValue = paramValue;
}
@Override
public Value get() {
return paramValue.getParameter();
}
@Override
public void set(Value val) {
paramValue.setParameter((VariableRef) val);
}
}
/**
* Pointer inside a pointer dererence value.
* Pointer inside a pointer derefence value.
*/
class ProgramValuePointer implements ProgramValue {
private final PointerDereference pointer;

View File

@ -234,6 +234,8 @@ public class ProgramValueIterator {
}
} else if(value instanceof LvalueIntermediate) {
subValues.add(new ProgramValue.ProgramValueLValueIntermediateVariable((LvalueIntermediate) value));
} else if(value instanceof ParamValue) {
subValues.add(new ProgramValue.ProgramValueParamValue((ParamValue) value));
} else if(value == null ||
value instanceof VariableRef ||
value instanceof VariableVersion ||

View File

@ -114,6 +114,8 @@ public class SymbolTypeInference {
}
} else if(rValue instanceof StructZero) {
return ((StructZero)rValue).getTypeStruct();
} else if(rValue instanceof ParamValue) {
return inferType(symbols, ((ParamValue) rValue).getParameter());
} else if(rValue instanceof StructUnwoundPlaceholder) {
return ((StructUnwoundPlaceholder) rValue).getTypeStruct();
}

View File

@ -0,0 +1,31 @@
package dk.camelot64.kickc.model.values;
import dk.camelot64.kickc.model.Program;
/** The value passed into a function for a specific parameter.
* Used for procedures that does not use {@link dk.camelot64.kickc.model.symbols.Procedure.CallingConvension#PHI_CALL}
* */
public class ParamValue implements RValue {
/** The (unversioned) parameter variable. */
VariableRef parameter;
public ParamValue(VariableRef parameter) {
this.parameter = parameter;
}
public VariableRef getParameter() {
return parameter;
}
public void setParameter(VariableRef parameter) {
this.parameter = parameter;
}
@Override
public String toString(Program program) {
return "param("+parameter.toString(program)+")";
}
}

View File

@ -209,6 +209,12 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
procedure.setParameters(parameterList);
sequence.addStatement(new StatementProcedureBegin(procedure.getRef(), StatementSource.procedureBegin(ctx), Comment.NO_COMMENTS));
// Add parameter assignments
if(Procedure.CallingConvension.STACK_CALL.equals(procedure.getCallingConvension())) {
for(Variable param : parameterList) {
sequence.addStatement(new StatementAssignment(param.getRef(), new ParamValue(param.getRef()), StatementSource.procedureEnd(ctx), Comment.NO_COMMENTS));
}
}
if(ctx.stmtSeq() != null) {
this.visit(ctx.stmtSeq());
}

View File

@ -104,6 +104,10 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
// New phi functions introduced in the block to create versions of variables.
Map<VariableUnversioned, VariableVersion> blockNewPhis = new LinkedHashMap<>();
ProgramValueIterator.execute(block, (programValue, currentStmt, stmtIt, currentBlock) -> {
if(programValue instanceof ProgramValue.ProgramValueParamValue) {
// Call parameter values should not be versioned
return;
}
Value value = programValue.get();
VariableVersion version = findOrCreateVersion(value, blockVersions, blockNewPhis);
if(version != null) {

View File

@ -2,6 +2,7 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.values.ForwardVariableRef;
import dk.camelot64.kickc.model.values.Value;
@ -21,6 +22,10 @@ public class Pass2AssertRValues extends Pass2SsaAssertion {
if(rValue instanceof ForwardVariableRef) {
throw new CompileError("No forward references allowed "+currentStmt.toString(getProgram(), false), currentStmt.getSource());
}
if(programValue instanceof ProgramValue.ProgramValueParamValue) {
// ParamValues are allowed to be unversioned
return;
}
if(rValue instanceof VariableRef) {
VariableRef variableRef = (VariableRef) rValue;
if(!variableRef.isIntermediate() && !variableRef.isVersion()) {

View File

@ -1,6 +1,7 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.statements.StatementCall;
import dk.camelot64.kickc.model.symbols.VariableVersion;
import dk.camelot64.kickc.model.values.VariableRef;
import dk.camelot64.kickc.model.statements.StatementAssignment;
@ -83,6 +84,16 @@ public class Pass4LiveRangeEquivalenceClassesFinalize extends Pass2Base {
return null;
}
@Override
public Void visitCall(StatementCall call) {
if(call.getlValue() instanceof VariableRef) {
VariableRef lValVar = (VariableRef) call.getlValue();
List<VariableRef> preferences = new ArrayList<>();
addToEquivalenceClassSet(lValVar, preferences);
}
return null;
}
private void addToEquivalenceClassSet(VariableRef lValVar, List<VariableRef> preferences) {
LiveRangeVariables liveRangeVariables = getProgram().getLiveRangeVariables();
LiveRangeEquivalenceClass lValEquivalenceClass =

View File

@ -35,6 +35,18 @@ public class TestPrograms {
public TestPrograms() {
}
/*
@Test
public void testProcedureCallingConventionStack1() throws IOException, URISyntaxException {
compileAndCompare("procedure-callingconvention-stack-1", log());
}
@Test
public void testProcedureCallingConventionStack0() throws IOException, URISyntaxException {
compileAndCompare("procedure-callingconvention-stack-0", log().verboseCreateSsa().verboseParse().verboseStatementSequence());
}
*/
@Test
public void testSignedCharComparison() throws IOException, URISyntaxException {
compileAndCompare("signed-char-comparison");
@ -55,18 +67,6 @@ public class TestPrograms {
compileAndCompare("stack-relative-addressing");
}
/*
@Test
public void testProcedureCallingConventionStack1() throws IOException, URISyntaxException {
compileAndCompare("procedure-callingconvention-stack-1", log());
}
@Test
public void testProcedureCallingConventionStack0() throws IOException, URISyntaxException {
compileAndCompare("procedure-callingconvention-stack-0", log().verboseCreateSsa().verboseParse().verboseStatementSequence());
}
*/
@Test
public void testStringPointerProblem() throws IOException, URISyntaxException {
compileAndCompare("string-pointer-problem");