From e4bf84c57c63cbf3df9230d9d2ec99420bd22093 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Wed, 8 Nov 2017 10:10:43 +0100 Subject: [PATCH] Improved call-path alias detection to inclide all call-parameters but no call-returns --- .../dk/camelot64/kickc/model/CallGraph.java | 6 +- .../camelot64/kickc/model/StatementBase.java | 14 +++++ .../Pass3LiveRangesEffectiveAnalysis.java | 58 ++++++++++++++----- 3 files changed, 60 insertions(+), 18 deletions(-) diff --git a/src/main/java/dk/camelot64/kickc/model/CallGraph.java b/src/main/java/dk/camelot64/kickc/model/CallGraph.java index 89b1e2cf2..2ae37e7af 100644 --- a/src/main/java/dk/camelot64/kickc/model/CallGraph.java +++ b/src/main/java/dk/camelot64/kickc/model/CallGraph.java @@ -210,10 +210,10 @@ public class CallGraph { @Override public String toString() { StringBuilder out = new StringBuilder(); - if (callStatementIdx != null) { - out.append(callStatementIdx).append(":"); - } out.append(procedure); + if (callStatementIdx != null) { + out.append(":").append(callStatementIdx); + } return out.toString(); } diff --git a/src/main/java/dk/camelot64/kickc/model/StatementBase.java b/src/main/java/dk/camelot64/kickc/model/StatementBase.java index e0c84130e..1acf95d37 100644 --- a/src/main/java/dk/camelot64/kickc/model/StatementBase.java +++ b/src/main/java/dk/camelot64/kickc/model/StatementBase.java @@ -56,6 +56,7 @@ public abstract class StatementBase implements Statement { LiveRangeVariablesEffective.AliveCombinations aliveCombinations = liveRangeVariablesEffective.getAliveCombinations(this); alive.append(" ( "); for (LiveRangeVariablesEffective.CallPath callPath : aliveCombinations.getCallPaths().getCallPaths()) { + alive.append(getCallPathString(callPath.getPath())); alive.append(getAliveString(aliveCombinations.getEffectiveAliveAtStmt(callPath))); alive.append(" "); } @@ -64,6 +65,19 @@ public abstract class StatementBase implements Statement { return alive.toString(); } + private String getCallPathString(List 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 alive) { StringBuilder str = new StringBuilder(); str.append(" [ "); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesEffectiveAnalysis.java b/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesEffectiveAnalysis.java index 0036292bb..12d0cf8e0 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesEffectiveAnalysis.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesEffectiveAnalysis.java @@ -102,11 +102,6 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base { callPaths = new LiveRangeVariablesEffective.CallPaths(procedureRef); Collection callers = 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) { // Each caller creates its own call-paths StatementCall callStatement = @@ -130,15 +125,7 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base { alive.addAll(callerPath.getAlive()); alive.removeAll(referencedInCaller); alive.addAll(liveRangeVariables.getAlive(callStatement)); - Pass2AliasElimination.Aliases aliases = new Pass2AliasElimination.Aliases(callerPath.getAliases()); - 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); - } - } - } + Pass2AliasElimination.Aliases aliases = getCallAliases(procedure, callBlock, callerPath); LiveRangeVariablesEffective.CallPath callPath = new LiveRangeVariablesEffective.CallPath(path, alive, aliases); callPaths.add(callPath); } @@ -148,7 +135,7 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base { rootPath.add(caller); ArrayList rootAlive = new ArrayList<>(); // 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); 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; + } }