mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-09-08 17:54:40 +00:00
Improved call-path alias detection to inclide all call-parameters but no call-returns
This commit is contained in:
parent
0026676080
commit
e4bf84c57c
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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(" [ ");
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user