From 4fd32274af11bd2ad18654a6003f134bdb9a5c07 Mon Sep 17 00:00:00 2001
From: jespergravgaard
Date: Wed, 8 Nov 2017 12:09:15 +0100
Subject: [PATCH] Working on handling procedure parameter aliases
---
.../model/LiveRangeVariablesEffective.java | 58 +++++++++++-----
.../kickc/passes/Pass2AliasElimination.java | 14 ++++
.../Pass3LiveRangesEffectiveAnalysis.java | 68 +++----------------
.../Pass4RegisterUpliftCombinations.java | 2 +-
4 files changed, 67 insertions(+), 75 deletions(-)
diff --git a/src/main/java/dk/camelot64/kickc/model/LiveRangeVariablesEffective.java b/src/main/java/dk/camelot64/kickc/model/LiveRangeVariablesEffective.java
index a58c4d37c..83cbf1c04 100644
--- a/src/main/java/dk/camelot64/kickc/model/LiveRangeVariablesEffective.java
+++ b/src/main/java/dk/camelot64/kickc/model/LiveRangeVariablesEffective.java
@@ -84,14 +84,19 @@ public class LiveRangeVariablesEffective {
*/
private Collection alive;
/**
- * Alias variables on the call-path. All global aliases plus any variables alias-assigned in a phi-block on the path.
+ * Alias variables for the innermost call. Variables alias-assigned as part of the innermost call on the path (in parameter assignment or phi block).
*/
- private Pass2AliasElimination.Aliases aliases;
+ private Pass2AliasElimination.Aliases innerAliases;
+ /**
+ * Alias variables from the entire call-path. Any variables alias-assigned as part of a call on the path (in parameter assignment or phi block).
+ */
+ private Pass2AliasElimination.Aliases pathAliases;
- public CallPath(List path, Collection alive, Pass2AliasElimination.Aliases aliases) {
+ public CallPath(List path, Collection alive, Pass2AliasElimination.Aliases innerAliases, Pass2AliasElimination.Aliases pathAliases) {
this.path = path;
this.alive = alive;
- this.aliases = aliases;
+ this.innerAliases = innerAliases;
+ this.pathAliases = pathAliases;
}
/**
@@ -111,11 +116,19 @@ public class LiveRangeVariablesEffective {
}
/**
- * Alias variables on the call-path. All global aliases plus any variables alias-assigned in a phi-block on the path.
+ * Alias variables from the entire call-path. Any variables alias-assigned as part of a call on the path (in parameter assignment or phi block).
* @return The aliases
*/
- public Pass2AliasElimination.Aliases getAliases() {
- return aliases;
+ public Pass2AliasElimination.Aliases getPathAliases() {
+ return pathAliases;
+ }
+
+ /**
+ * Alias variables for the innermost call. Variables alias-assigned as part of the innermost call on the path (in parameter assignment or phi block).
+ * @return The aliases
+ */
+ public Pass2AliasElimination.Aliases getInnerAliases() {
+ return innerAliases;
}
}
@@ -141,8 +154,9 @@ public class LiveRangeVariablesEffective {
/**
* Get all combinations of variables alive at a statement.
* If the statement is inside a method the different combinations in the result arises from different calls of the method
- * (recursively up til the main()-method.
+ * (recursively up til the main()-method.)
* Each combination includes all variables alive at the exit of any surrounding call.
+ * Also includes variable aliases that are part of the parameter assignments to the calls on the path.
*
*
* @param statement The statement to examine
@@ -163,6 +177,9 @@ public class LiveRangeVariablesEffective {
callPaths = new CallPaths(Procedure.ROOT);
referencedInProcedure = new ArrayList<>();
}
+ // Examine if the statement is a parameter assignment before a call
+ throw new RuntimeException("Examine if the statement is a parameter assignment before a call - and add the inner aliases if it is");
+
return new AliveCombinations(callPaths, referencedInProcedure, aliveAtStmt);
}
@@ -185,25 +202,22 @@ public class LiveRangeVariablesEffective {
* Variables alive at the statement inside the procedure.
*/
private Collection aliveAtStmt;
+ /**
+ * If the statement is an assignment to a call parameter this contains the aliases for that specific call.
+ */
+ private Pass2AliasElimination.Aliases callAliases;
- public AliveCombinations(CallPaths callPaths, Collection referencedInProcedure, Collection aliveAtStmt) {
+ public AliveCombinations(CallPaths callPaths, Collection referencedInProcedure, Collection aliveAtStmt, Pass2AliasElimination.Aliases callAliases) {
this.callPaths = callPaths;
this.referencedInProcedure = referencedInProcedure;
this.aliveAtStmt = aliveAtStmt;
+ this.callAliases = callAliases;
}
public CallPaths getCallPaths() {
return callPaths;
}
- public Collection getReferencedInProcedure() {
- return referencedInProcedure;
- }
-
- public Collection getAliveAtStmt() {
- return aliveAtStmt;
- }
-
/**
* Get all variables effective alive at the statement for a specific call path.
* @param callPath The call path (returned from getCallPaths)
@@ -220,6 +234,16 @@ public class LiveRangeVariablesEffective {
return effectiveAlive;
}
+ public Pass2AliasElimination.Aliases getEffectiveAliasesAtStmt(CallPath callPath) {
+ if(callAliases==null) {
+ return callPath.getPathAliases();
+ } else {
+ Pass2AliasElimination.Aliases aliases = new Pass2AliasElimination.Aliases();
+ aliases.addAll(callPath.getPathAliases());
+ aliases.addAll(callAliases);
+ return aliases;
+ }
+ }
}
diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2AliasElimination.java b/src/main/java/dk/camelot64/kickc/passes/Pass2AliasElimination.java
index 065d7d62f..726d1416a 100644
--- a/src/main/java/dk/camelot64/kickc/passes/Pass2AliasElimination.java
+++ b/src/main/java/dk/camelot64/kickc/passes/Pass2AliasElimination.java
@@ -157,6 +157,20 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
public List getAliasSets() {
return aliases;
}
+
+ public void addAll(Aliases aliases) {
+ for (AliasSet aliasSet : aliases.getAliasSets()) {
+ List vars = aliasSet.getVars();
+ VariableRef first = null;
+ for (VariableRef var : vars) {
+ if(first==null) {
+ first = var;
+ } else {
+ add(first, var);
+ }
+ }
+ }
+ }
}
public static class AliasSet {
diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesEffectiveAnalysis.java b/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesEffectiveAnalysis.java
index 12d0cf8e0..a5523c5c9 100644
--- a/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesEffectiveAnalysis.java
+++ b/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesEffectiveAnalysis.java
@@ -39,54 +39,6 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
//getLog().append("Calculated effective variable live ranges");
}
- /**
- * Get all variables alive at a statement.
- * If the statement is inside a method this also includes all variables alive at the exit of the calls.
- *
- * This method requires a number of other analysis to be present and updated in the (global) program - especailly the Call Graph.
- *
- * @param statement The statement to examine
- * @return All variables alive at the statement
- */
- private Collection> findAliveEffective(LiveRangeVariables liveRangeVariables, Statement statement) {
- Set> combinations = new LinkedHashSet<>();
- // Get variables alive from live range analysis
- Collection effectiveAlive = liveRangeVariables.getAlive(statement);
- // If the statement is inside a method recurse back to all calls
- // For each call add the variables alive after the call that are not referenced (used/defined) inside the method
- ControlFlowBlock block = getProgram().getGraph().getBlockFromStatementIdx(statement.getIndex());
- ScopeRef scopeRef = block.getScope();
- Scope scope = getProgram().getScope().getScope(scopeRef);
- if (scope instanceof Procedure) {
- Procedure procedure = (Procedure) scope;
- Collection callers =
- getProgram().getCallGraph().getCallers(procedure.getLabel().getRef());
- Collection referencedInProcedure = referenceInfo.getReferenced(procedure.getRef().getLabelRef());
- for (CallGraph.CallBlock.Call caller : callers) {
- // Each caller creates its own combinations
- StatementCall callStatement =
- (StatementCall) getProgram().getGraph().getStatementByIndex(caller.getCallStatementIdx());
- Collection> callerCombinations = findAliveEffective(liveRangeVariables, callStatement);
- for (Collection callerCombination : callerCombinations) {
- LinkedHashSet combination = new LinkedHashSet<>();
- // Add alive at call
- combination.addAll(callerCombination);
- // Clear out any variables referenced in the method
- combination.removeAll(referencedInProcedure);
- // Add alive at statement
- combination.addAll(effectiveAlive);
- // Add combination
- combinations.add(combination);
- }
- }
- }
- if(combinations.size()==0) {
- // Add the combination at the current statement if no other combinations have been created
- combinations.add(effectiveAlive);
- }
- return combinations;
- }
-
private void populateProcedureCallPaths() {
this.procedureCallPaths = new LinkedHashMap<>();
Collection procedures = getProgram().getScope().getAllProcedures(true);
@@ -125,8 +77,11 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
alive.addAll(callerPath.getAlive());
alive.removeAll(referencedInCaller);
alive.addAll(liveRangeVariables.getAlive(callStatement));
- Pass2AliasElimination.Aliases aliases = getCallAliases(procedure, callBlock, callerPath);
- LiveRangeVariablesEffective.CallPath callPath = new LiveRangeVariablesEffective.CallPath(path, alive, aliases);
+ Pass2AliasElimination.Aliases innerAliases = getCallAliases(procedure, callBlock);
+ Pass2AliasElimination.Aliases pathAliases = new Pass2AliasElimination.Aliases();
+ pathAliases.addAll(callerPath.getPathAliases());
+ pathAliases.addAll(innerAliases);
+ LiveRangeVariablesEffective.CallPath callPath = new LiveRangeVariablesEffective.CallPath(path, alive, innerAliases, pathAliases);
callPaths.add(callPath);
}
} else {
@@ -134,9 +89,9 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
ArrayList rootPath = new ArrayList<>();
rootPath.add(caller);
ArrayList rootAlive = new ArrayList<>();
- // Initialize with global cross-scope aliases
+ // Initialize with global cross-scope aliases (assumed empty)
Pass2AliasElimination.Aliases rootAliases = new Pass2AliasElimination.Aliases();
- LiveRangeVariablesEffective.CallPath rootCallPath = new LiveRangeVariablesEffective.CallPath(rootPath, rootAlive, rootAliases);
+ LiveRangeVariablesEffective.CallPath rootCallPath = new LiveRangeVariablesEffective.CallPath(rootPath, rootAlive, rootAliases, rootAliases);
callPaths.add(rootCallPath);
}
}
@@ -146,18 +101,17 @@ 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 procedure 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) {
+ private Pass2AliasElimination.Aliases getCallAliases(Procedure procedure, ControlFlowBlock callBlock) {
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());
+ Pass2AliasElimination.Aliases aliases = new Pass2AliasElimination.Aliases();
// Find aliases inside the phi-block of the called method
if(procedurePhiBlock!=null) {
for (StatementPhiBlock.PhiVariable phiVariable : procedurePhiBlock.getPhiVariables()) {
@@ -167,7 +121,7 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
}
}
}
- // Find call parameter aliasses in the calling block before the call
+ // Find call parameter aliases in the calling block before the call
for (Statement statement : callBlock.getStatements()) {
if(statement instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) statement;
diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java
index cc6933ca7..5a22ccea4 100644
--- a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java
+++ b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java
@@ -221,7 +221,7 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
for (LiveRangeVariablesEffective.CallPath callPath : aliveCombinations.getCallPaths().getCallPaths()) {
LinkedHashMap usedRegisters = new LinkedHashMap<>();
Collection alive = aliveCombinations.getEffectiveAliveAtStmt(callPath);
- Pass2AliasElimination.Aliases callPathAliases = callPath.getAliases();
+ Pass2AliasElimination.Aliases callPathAliases = aliveCombinations.getEffectiveAliasesAtStmt(callPath);
for (VariableRef varRef : alive) {
Variable var = programScope.getVariable(varRef);
Registers.Register allocation = var.getAllocation();