mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-17 10:30:43 +00:00
Added ParamValue RValue for retrieving parameter values in procedures. #316
This commit is contained in:
parent
70435aec30
commit
6e767862e8
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 ||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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)+")";
|
||||
}
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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()) {
|
||||
|
@ -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 =
|
||||
|
@ -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");
|
||||
|
Loading…
x
Reference in New Issue
Block a user