mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-26 18:29:54 +00:00
Rewrote calling convention PHI return value pass.
This commit is contained in:
parent
f32f44cd92
commit
002c498810
@ -280,7 +280,7 @@ public class Compiler {
|
|||||||
//getLog().append("CONTROL FLOW GRAPH (SSA)");
|
//getLog().append("CONTROL FLOW GRAPH (SSA)");
|
||||||
//getLog().append(program.getGraph().toString(program));
|
//getLog().append(program.getGraph().toString(program));
|
||||||
|
|
||||||
program.setGraph(new Pass1ProcedureCallsReturnValue(program).generate());
|
new Pass1CallingConventionPhiReturnValue(program).execute();
|
||||||
//getLog().append("CONTROL FLOW GRAPH (BEFORE LIST UNWINDING)");
|
//getLog().append("CONTROL FLOW GRAPH (BEFORE LIST UNWINDING)");
|
||||||
//getLog().append(program.getGraph().toString(program));
|
//getLog().append(program.getGraph().toString(program));
|
||||||
new PassNUnwindLValueLists(program).execute();
|
new PassNUnwindLValueLists(program).execute();
|
||||||
|
@ -8,42 +8,61 @@ import dk.camelot64.kickc.model.symbols.Procedure;
|
|||||||
import dk.camelot64.kickc.model.types.SymbolType;
|
import dk.camelot64.kickc.model.types.SymbolType;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.ListIterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pass that modifies a control flow graph to call procedures by passing return value through registers for {@link Procedure.CallingConvention#PHI_CALL}
|
* Handles return values for {@link Procedure.CallingConvention#PHI_CALL} procedure calls by passing the return value through variable versions.
|
||||||
*/
|
*/
|
||||||
public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor {
|
public class Pass1CallingConventionPhiReturnValue {
|
||||||
|
|
||||||
private Program program;
|
private Program program;
|
||||||
|
|
||||||
public Pass1ProcedureCallsReturnValue(Program program) {
|
public Pass1CallingConventionPhiReturnValue(Program program) {
|
||||||
this.program = program;
|
this.program = program;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControlFlowGraph generate() {
|
public void execute() {
|
||||||
ControlFlowGraph generated = visitGraph(program.getGraph());
|
for(ControlFlowBlock block : program.getGraph().getAllBlocks()) {
|
||||||
return generated;
|
ListIterator<Statement> stmtIt = block.getStatements().listIterator();
|
||||||
}
|
while(stmtIt.hasNext()) {
|
||||||
|
Statement statement = stmtIt.next();
|
||||||
@Override
|
if(statement instanceof StatementCall) {
|
||||||
public StatementCall visitCall(StatementCall origCall) {
|
StatementCall call = (StatementCall) statement;
|
||||||
// Procedure strategy implemented is currently variable-based transfer of parameters/return values
|
ProcedureRef procedureRef = call.getProcedure();
|
||||||
// Generate return value assignment
|
Procedure procedure = program.getScope().getProcedure(procedureRef);
|
||||||
ProcedureRef procedureRef = origCall.getProcedure();
|
if(Procedure.CallingConvention.PHI_CALL.equals(procedure.getCallingConvention())) {
|
||||||
Procedure procedure = program.getScope().getProcedure(procedureRef);
|
handlePhiCall(call, procedure, block, stmtIt);
|
||||||
// If not PHI-call - skip
|
}
|
||||||
if(!Procedure.CallingConvention.PHI_CALL.equals(procedure.getCallingConvention())) {
|
}
|
||||||
StatementCall copyCall = super.visitCall(origCall);
|
}
|
||||||
copyCall.setProcedure(procedureRef);
|
|
||||||
return copyCall;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String procedureName = origCall.getProcedureName();
|
for(ControlFlowBlock block : program.getGraph().getAllBlocks()) {
|
||||||
StatementCall copyCall = new StatementCall(null, procedureName, null, origCall.getSource(), origCall.getComments());
|
for(Statement statement : block.getStatements()) {
|
||||||
copyCall.setProcedure(procedureRef);
|
if(statement instanceof StatementReturn) {
|
||||||
addStatementToCurrentBlock(copyCall);
|
StatementReturn statementReturn = (StatementReturn) statement;
|
||||||
getCurrentBlock().setCallSuccessor(procedure.getLabel().getRef());
|
Procedure procedure = (Procedure) program.getScope().getScope(block.getScope());
|
||||||
|
if(Procedure.CallingConvention.PHI_CALL.equals(procedure.getCallingConvention())) {
|
||||||
|
statementReturn.setValue(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle PHI-call by assigning return value to LValue and updating all variables modified inside the procedure.
|
||||||
|
* @param call The call statement
|
||||||
|
* @param procedure The procedure
|
||||||
|
* @param block The block containing the call
|
||||||
|
* @param stmtIt Iterator used for adding statements
|
||||||
|
*/
|
||||||
|
void handlePhiCall(StatementCall call, Procedure procedure, ControlFlowBlock block, ListIterator<Statement> stmtIt) {
|
||||||
|
// Generate return value assignment
|
||||||
|
block.setCallSuccessor(procedure.getLabel().getRef());
|
||||||
if(!SymbolType.VOID.equals(procedure.getReturnType())) {
|
if(!SymbolType.VOID.equals(procedure.getReturnType())) {
|
||||||
// Find return variable final version
|
// Find return variable final version
|
||||||
Label returnBlockLabel = procedure.getLabel(SymbolRef.PROCEXIT_BLOCK_NAME);
|
Label returnBlockLabel = procedure.getLabel(SymbolRef.PROCEXIT_BLOCK_NAME);
|
||||||
@ -63,12 +82,14 @@ public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor
|
|||||||
if(returnVarFinal == null) {
|
if(returnVarFinal == null) {
|
||||||
throw new RuntimeException("Error! Cannot find final return variable for " + procedure.getFullName());
|
throw new RuntimeException("Error! Cannot find final return variable for " + procedure.getFullName());
|
||||||
}
|
}
|
||||||
StatementAssignment returnAssignment = new StatementAssignment(origCall.getlValue(), returnVarFinal, origCall.isInitialAssignment(), origCall.getSource(), new ArrayList<>());
|
// Add assignment of final return variable version to lValue
|
||||||
addStatementToCurrentBlock(returnAssignment);
|
StatementAssignment returnAssignment = new StatementAssignment(call.getlValue(), returnVarFinal, call.isInitialAssignment(), call.getSource(), new ArrayList<>());
|
||||||
|
stmtIt.add(returnAssignment);
|
||||||
|
call.setlValue(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Patch versions of rValues in assignments for vars modified in the call
|
// Patch versions of rValues in assignments for vars modified in the call
|
||||||
LabelRef successor = getOrigBlock().getDefaultSuccessor();
|
LabelRef successor = block.getDefaultSuccessor();
|
||||||
ControlFlowBlock successorBlock = program.getGraph().getBlock(successor);
|
ControlFlowBlock successorBlock = program.getGraph().getBlock(successor);
|
||||||
Set<VariableRef> modifiedVars = program.getProcedureModifiedVars().getModifiedVars(procedure.getRef());
|
Set<VariableRef> modifiedVars = program.getProcedureModifiedVars().getModifiedVars(procedure.getRef());
|
||||||
for(Statement statement : successorBlock.getStatements()) {
|
for(Statement statement : successorBlock.getStatements()) {
|
||||||
@ -79,7 +100,7 @@ public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor
|
|||||||
VariableRef unversionedVar = new VariableRef(phiVar.getFullNameUnversioned());
|
VariableRef unversionedVar = new VariableRef(phiVar.getFullNameUnversioned());
|
||||||
if(modifiedVars.contains(unversionedVar)) {
|
if(modifiedVars.contains(unversionedVar)) {
|
||||||
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
|
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
|
||||||
if(phiRValue.getPredecessor().equals(getOrigBlock().getLabel())) {
|
if(phiRValue.getPredecessor().equals(block.getLabel())) {
|
||||||
VariableRef procReturnVersion = findReturnVersion(procedure, unversionedVar);
|
VariableRef procReturnVersion = findReturnVersion(procedure, unversionedVar);
|
||||||
phiRValue.setrValue(procReturnVersion);
|
phiRValue.setrValue(procReturnVersion);
|
||||||
}
|
}
|
||||||
@ -89,7 +110,6 @@ public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private VariableRef findReturnVersion(Procedure procedure, VariableRef assignedVar) {
|
private VariableRef findReturnVersion(Procedure procedure, VariableRef assignedVar) {
|
||||||
@ -110,17 +130,5 @@ public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor
|
|||||||
throw new RuntimeException("Variable " + assignedVar + "modified by procedure " + procedure + " not found in @return block " + block.getLabel());
|
throw new RuntimeException("Variable " + assignedVar + "modified by procedure " + procedure + " not found in @return block " + block.getLabel());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public StatementReturn visitReturn(StatementReturn orig) {
|
|
||||||
ControlFlowBlock currentBlock = getCurrentBlock();
|
|
||||||
String currentProcName = currentBlock.getLabel().getScopeNames();
|
|
||||||
Procedure procedure = program.getScope().getProcedure(currentProcName);
|
|
||||||
// If not PHI-call - skip
|
|
||||||
if(!Procedure.CallingConvention.PHI_CALL.equals(procedure.getCallingConvention()))
|
|
||||||
return super.visitReturn(orig);
|
|
||||||
|
|
||||||
addStatementToCurrentBlock(new StatementReturn(null, orig.getSource(), orig.getComments()));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user