1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-08-02 09:29:35 +00:00

Improved call-path alias detection to inclide all call-parameters but no call-returns

This commit is contained in:
jespergravgaard 2017-11-08 10:10:43 +01:00
parent 0026676080
commit e4bf84c57c
3 changed files with 60 additions and 18 deletions

View File

@ -210,10 +210,10 @@ public class CallGraph {
@Override @Override
public String toString() { public String toString() {
StringBuilder out = new StringBuilder(); StringBuilder out = new StringBuilder();
if (callStatementIdx != null) {
out.append(callStatementIdx).append(":");
}
out.append(procedure); out.append(procedure);
if (callStatementIdx != null) {
out.append(":").append(callStatementIdx);
}
return out.toString(); return out.toString();
} }

View File

@ -56,6 +56,7 @@ public abstract class StatementBase implements Statement {
LiveRangeVariablesEffective.AliveCombinations aliveCombinations = liveRangeVariablesEffective.getAliveCombinations(this); LiveRangeVariablesEffective.AliveCombinations aliveCombinations = liveRangeVariablesEffective.getAliveCombinations(this);
alive.append(" ( "); alive.append(" ( ");
for (LiveRangeVariablesEffective.CallPath callPath : aliveCombinations.getCallPaths().getCallPaths()) { for (LiveRangeVariablesEffective.CallPath callPath : aliveCombinations.getCallPaths().getCallPaths()) {
alive.append(getCallPathString(callPath.getPath()));
alive.append(getAliveString(aliveCombinations.getEffectiveAliveAtStmt(callPath))); alive.append(getAliveString(aliveCombinations.getEffectiveAliveAtStmt(callPath)));
alive.append(" "); alive.append(" ");
} }
@ -64,6 +65,19 @@ public abstract class StatementBase implements Statement {
return alive.toString(); return alive.toString();
} }
private String getCallPathString(List<CallGraph.CallBlock.Call> path) {
StringBuilder out = new StringBuilder();
boolean first = true;
for (CallGraph.CallBlock.Call call : path) {
if(!first) {
out.append("::");
}
first = false;
out.append(call.toString());
}
return out.toString();
}
private String getAliveString(Collection<VariableRef> alive) { private String getAliveString(Collection<VariableRef> alive) {
StringBuilder str = new StringBuilder(); StringBuilder str = new StringBuilder();
str.append(" [ "); str.append(" [ ");

View File

@ -102,11 +102,6 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
callPaths = new LiveRangeVariablesEffective.CallPaths(procedureRef); callPaths = new LiveRangeVariablesEffective.CallPaths(procedureRef);
Collection<CallGraph.CallBlock.Call> callers = Collection<CallGraph.CallBlock.Call> callers =
getProgram().getCallGraph().getCallers(procedure.getLabel().getRef()); getProgram().getCallGraph().getCallers(procedure.getLabel().getRef());
ControlFlowBlock procedureBlock = getProgram().getGraph().getBlock(procedure.getLabel().getRef());
StatementPhiBlock procedurePhiBlock = null;
if(procedureBlock.hasPhiBlock()) {
procedurePhiBlock = procedureBlock.getPhiBlock();
}
for (CallGraph.CallBlock.Call caller : callers) { for (CallGraph.CallBlock.Call caller : callers) {
// Each caller creates its own call-paths // Each caller creates its own call-paths
StatementCall callStatement = StatementCall callStatement =
@ -130,15 +125,7 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
alive.addAll(callerPath.getAlive()); alive.addAll(callerPath.getAlive());
alive.removeAll(referencedInCaller); alive.removeAll(referencedInCaller);
alive.addAll(liveRangeVariables.getAlive(callStatement)); alive.addAll(liveRangeVariables.getAlive(callStatement));
Pass2AliasElimination.Aliases aliases = new Pass2AliasElimination.Aliases(callerPath.getAliases()); Pass2AliasElimination.Aliases aliases = getCallAliases(procedure, callBlock, callerPath);
if(procedurePhiBlock!=null) {
for (StatementPhiBlock.PhiVariable phiVariable : procedurePhiBlock.getPhiVariables()) {
RValue phiRvalue = phiVariable.getrValue(callBlock.getLabel());
if (phiRvalue instanceof VariableRef) {
aliases.add(phiVariable.getVariable(), (VariableRef) phiRvalue);
}
}
}
LiveRangeVariablesEffective.CallPath callPath = new LiveRangeVariablesEffective.CallPath(path, alive, aliases); LiveRangeVariablesEffective.CallPath callPath = new LiveRangeVariablesEffective.CallPath(path, alive, aliases);
callPaths.add(callPath); callPaths.add(callPath);
} }
@ -148,7 +135,7 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
rootPath.add(caller); rootPath.add(caller);
ArrayList<VariableRef> rootAlive = new ArrayList<>(); ArrayList<VariableRef> rootAlive = new ArrayList<>();
// Initialize with global cross-scope aliases // Initialize with global cross-scope aliases
Pass2AliasElimination.Aliases rootAliases = Pass2AliasElimination.findAliases(getProgram(), true); Pass2AliasElimination.Aliases rootAliases = new Pass2AliasElimination.Aliases();
LiveRangeVariablesEffective.CallPath rootCallPath = new LiveRangeVariablesEffective.CallPath(rootPath, rootAlive, rootAliases); LiveRangeVariablesEffective.CallPath rootCallPath = new LiveRangeVariablesEffective.CallPath(rootPath, rootAlive, rootAliases);
callPaths.add(rootCallPath); callPaths.add(rootCallPath);
} }
@ -157,6 +144,47 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
} }
} }
/**
* Find aliases defined when taking a specific call - meaning call parameters that have specific values when taking the specific call.
* @param procedurePhiBlock The phi-block of the called procedure
* @param callBlock The block performing the call
* @param callerPath The call-path from main() to the calling procedure. (contains aliases for all preceding calls)
* @return Aliases defined by the specific call.
*/
private Pass2AliasElimination.Aliases getCallAliases(Procedure procedure, ControlFlowBlock callBlock, LiveRangeVariablesEffective.CallPath callerPath) {
ControlFlowBlock procedureBlock = getProgram().getGraph().getBlock(procedure.getLabel().getRef());
StatementPhiBlock procedurePhiBlock = null;
if(procedureBlock.hasPhiBlock()) {
procedurePhiBlock = procedureBlock.getPhiBlock();
}
Pass2AliasElimination.Aliases aliases = new Pass2AliasElimination.Aliases(callerPath.getAliases());
// Find aliases inside the phi-block of the called method
if(procedurePhiBlock!=null) {
for (StatementPhiBlock.PhiVariable phiVariable : procedurePhiBlock.getPhiVariables()) {
RValue phiRvalue = phiVariable.getrValue(callBlock.getLabel());
if (phiRvalue instanceof VariableRef) {
aliases.add(phiVariable.getVariable(), (VariableRef) phiRvalue);
}
}
}
// Find call parameter aliasses in the calling block before the call
for (Statement statement : callBlock.getStatements()) {
if(statement instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) statement;
LValue lValue = assignment.getlValue();
if(lValue instanceof VariableRef) {
Variable lValueVar = getProgram().getScope().getVariable((VariableRef) lValue);
if(lValueVar.getScope().equals(procedure)) {
// Assigning into the procedure scope
if(assignment.getrValue1()==null && assignment.getOperator()==null && assignment.getrValue2() instanceof VariableRef) {
aliases.add((VariableRef) lValue, (VariableRef) assignment.getrValue2());
}
}
}
}
}
return aliases;
}
} }