Skip to content
Open
Show file tree
Hide file tree
Changes from 63 commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
b3973dc
Implement dominance tree
mateusluizfb Oct 31, 2020
5811942
Implement dominance frontier
mateusluizfb Oct 31, 2020
4a01850
Fix some paths
mateusluizfb Oct 31, 2020
f163807
Implement a first version of the phi-function insertion
mateusluizfb Nov 9, 2020
6d0da73
Some fixes in the phi insertion
mateusluizfb Nov 12, 2020
17b8862
Refactor phi function insertion
mateusluizfb Nov 12, 2020
0cfca0e
Create variable renaming module
mateusluizfb Nov 20, 2020
2006b29
Remove phi function extracted code
mateusluizfb Nov 24, 2020
d51d120
Add Stack implementation code
mateusluizfb Nov 24, 2020
56e18d5
Import stack in the variable renaming code
mateusluizfb Nov 24, 2020
ad0e7fa
Remove Util code and leave in the modules
mateusluizfb Nov 30, 2020
5939bfb
Rename stack's empty() to emptyStack()
mateusluizfb Dec 2, 2020
5a17d79
Implement first part of the variable renaming
mateusluizfb Dec 2, 2020
74f80c0
Fix some mehods arguments
mateusluizfb Jan 5, 2021
22245ce
Creating a new variable version
mateusluizfb Jan 7, 2021
6f5480b
Fix stack peeek for int value
mateusluizfb Jan 7, 2021
b4ff2af
Correctly verify right hand side variables
mateusluizfb Jan 11, 2021
1848186
Change right hand side list iteration
mateusluizfb Jan 12, 2021
37f4e88
Fix right hand side iteration
mateusluizfb Jan 17, 2021
0bcad7c
Only insert phi functions in join nodes
mateusluizfb Jan 17, 2021
f48f3d2
Replace a simple right hand side variable
mateusluizfb Jan 17, 2021
767f49b
Fix left variable replacement
mateusluizfb Jan 21, 2021
6733177
Usign block by block DFS instead the common variable iteration
mateusluizfb Jan 21, 2021
9e9753a
Beginning to phi function renaming
mateusluizfb Jan 21, 2021
fee15d2
Change the block iteration strategy
mateusluizfb Jan 28, 2021
0c7ee20
Adjust left and right hand side renaming
mateusluizfb Jan 28, 2021
2bd3ae2
Adjust tests setup
mateusluizfb Jan 28, 2021
25dc1f1
Pop queue in the end of each execution
mateusluizfb Feb 1, 2021
684f585
Starting to rename another variable in deeper immediates
mateusluizfb Feb 2, 2021
6135298
Refact Variable Renaming
mateusluizfb Feb 2, 2021
2ea8a77
Refactor variable renaming
mateusluizfb Feb 3, 2021
fb3ff82
Adding and moving ssa tests
mateusluizfb Feb 6, 2021
f90cb73
Remove unused test from VariableRenaming
mateusluizfb Feb 6, 2021
ff486fd
Merge branch 'master' into feature/variable-renaming
mateusluizfb Feb 8, 2021
1fc6056
Fix ssa tests namespace
mateusluizfb Feb 8, 2021
488fa1e
Update phi function insertion
mateusluizfb Feb 8, 2021
5063f8e
Chante test classfile
mateusluizfb Feb 10, 2021
394a082
Update java 8 test file
mateusluizfb Feb 10, 2021
55863c2
Rename left hand side of a phiFunction
mateusluizfb Feb 15, 2021
6e3c843
Test a simple exception case
mateusluizfb Feb 15, 2021
2b9645c
Refactor stack of variable version access
mateusluizfb Feb 19, 2021
03d6a00
Refactor variable version stacks access
mateusluizfb Feb 19, 2021
3f069ce
Use string as key in the variable version stack
mateusluizfb Feb 19, 2021
f523e55
Match only local immediates with name
mateusluizfb Feb 19, 2021
43737be
Fix assignment check without args case
mateusluizfb Feb 19, 2021
7561cd0
DFS through an idom tree instead the CFG
mateusluizfb Feb 20, 2021
98c04df
Create a module to run the SSA transformation
mateusluizfb Feb 22, 2021
f79e8db
Add some tests to the SSA generator
mateusluizfb Feb 22, 2021
62df263
Rename invoke args
mateusluizfb Feb 23, 2021
6020750
Match method invoke with the right matchs
mateusluizfb Feb 25, 2021
b05df0f
Unsupport invokeStmt operators when applying SSA transformation
mateusluizfb Feb 25, 2021
40c72e5
Adding some comments
mateusluizfb Feb 25, 2021
a366970
Rename rhs expressions
mateusluizfb Feb 26, 2021
f5fee38
Fix phiFunction renaming by looking up via DFS
mateusluizfb Feb 26, 2021
ccc7921
Adding support for left hand side array
mateusluizfb Feb 27, 2021
453ddf2
Support right hand side array
mateusluizfb Feb 27, 2021
140555e
Test soot example code
mateusluizfb Feb 27, 2021
de2ad22
Organazing some tests
mateusluizfb Mar 8, 2021
0c08d53
Refacto SSA integration tests
mateusluizfb Mar 10, 2021
e34d1af
Add new test samples
mateusluizfb Mar 10, 2021
a08c8ef
Add test for all math problems
mateusluizfb Mar 11, 2021
1628f80
Add comment to test
mateusluizfb Mar 23, 2021
5cf7d66
Rename variable renaming stacks
mateusluizfb Mar 23, 2021
8330998
Refactor phi-function insertion module
mateusluizfb Mar 24, 2021
5da3143
Revert pom.xml
mateusluizfb Jun 8, 2021
35477ef
Merge branch 'master' into feature/variable-renaming
mateusluizfb Jun 8, 2021
960c69a
Extracting helper methods to another file
mateusluizfb Jun 13, 2021
e8a8731
Fix CI build issues
mateusluizfb Jun 13, 2021
1b6f132
Fix tests
mateusluizfb Jun 14, 2021
02452bf
Rewrite phi-function insertion algorithm
mateusluizfb Jun 16, 2021
9d0c4e1
Rewrite dominance-frontier creation algorithm
mateusluizfb Jun 16, 2021
66f2e5d
Minor fixes in the phi-function insertion
mateusluizfb Jun 16, 2021
d8a7384
Refactor dominance tree creation
mateusluizfb Jun 17, 2021
6267bbc
Simpler dom frontier implementation
mateusluizfb Jun 17, 2021
44b6cf2
Revert "Simpler dom frontier implementation"
mateusluizfb Jun 17, 2021
d457b36
Implement the more efficient way compute dom frontier
mateusluizfb Jun 17, 2021
2fdcf78
Fix dominance frontier test
mateusluizfb Jun 18, 2021
f230dc5
Fix tests and run phi insertion for join nodes only
mateusluizfb Jun 20, 2021
8fc6e15
Fixing some tests
mateusluizfb Jun 20, 2021
ad31c15
Simplify again the dominance frontier algorithm
mateusluizfb Jun 20, 2021
493ce83
Fix some tests
mateusluizfb Jun 21, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions .classpath
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src/main/rascal"/>
<classpathentry kind="src" path="src/test/java"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src/test/rascal"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
Expand All @@ -15,5 +26,11 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>
4 changes: 3 additions & 1 deletion src/main/java/lang/jimple/util/Pair.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package lang.jimple.util;

import lang.jimple.internal.generated.Type;
import lang.jimple.internal.generated.Value;

import lombok.AllArgsConstructor;
import lombok.Data;

Expand All @@ -9,5 +12,4 @@ public class Pair<First, Second> {

First first;
Second second;

}
1 change: 1 addition & 0 deletions src/main/rascal/lang/jimple/core/Syntax.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ data Expression
| lengthOf(Immediate immediate)
| neg(Immediate immediate)
| immediate(Immediate immediate)
| phiFunction(Variable variable, list[Variable] definitions)
;

data ArrayDescriptor
Expand Down
2 changes: 1 addition & 1 deletion src/main/rascal/lang/jimple/decompiler/Decompiler.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Exception;

@javaClass{lang.jimple.internal.Decompiler}
@reflect{for stdout}
java ClassOrInterfaceDeclaration decompile(loc classFile) throws IO;
java ClassOrInterfaceDeclaration decompile(loc classFile) throws IO;



34 changes: 34 additions & 0 deletions src/main/rascal/lang/jimple/toolkit/ssa/DominanceFrontier.rsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module lang::jimple::toolkit::ssa::DominanceFrontier

import Set;
import analysis::graphs::Graph;
import lang::jimple::toolkit::FlowGraph;
import lang::jimple::toolkit::ssa::DominanceTree;

public map[Node, set[Node]] createDominanceFrontier(FlowGraph flowGraph, map[&T, set[&T]] dominanceTree) {
dominanceFrontiers = ();

for(<origin, child> <- flowGraph) {
if(true)
dominanceFrontiers = calculateDominanceFrontier(origin, child, dominanceFrontiers, dominanceTree);
};

return dominanceFrontiers;
}

public map[Node, set[Node]] calculateDominanceFrontier(Node origin, Node destination, map[Node, set[Node]] dominanceFrontier, map[&T, set[&T]] dominanceTree) {
temp = origin;

while(temp != findIdom(dominanceTree, destination)) {
originDominanceFrontierValue = if(dominanceFrontier[temp]?) dominanceFrontier[temp]; else {};
dominanceFrontier[temp] = originDominanceFrontierValue + {destination};

temp = findIdom(dominanceTree, temp);
};

return dominanceFrontier;
}

public bool isJoinNode(FlowGraph flowGraph, Node child) {
return size(predecessors(flowGraph, child)) >= 2;
}
62 changes: 54 additions & 8 deletions src/main/rascal/lang/jimple/toolkit/ssa/DominanceTree.rsc
Original file line number Diff line number Diff line change
@@ -1,16 +1,62 @@
module lang::jimple::toolkit::ssa::DominanceTree

import demo::Dominators;
import Set;
import Relation;
import lang::jimple::toolkit::FlowGraph;
import analysis::graphs::Graph;

import List;
public map[&T, set[&T]] createDominanceTree(Graph[&T] graph) {
PRED = graph;
ROOT = entryNode();

public map[Node, Node] createDominanceTree(FlowGraph flowGraph) {
result = (computeDominator(flowGraph, a): a | <a, _> <- flowGraph);
return result;
set[&T] rootDominators = reachX(PRED, {ROOT}, {});
set[&T] VERTICES = carrier(PRED);

temp = dominators(PRED, ROOT);

return (V: (rootDominators - reachX(removeNodeFromGraph(graph, V), {ROOT}, {V}) - {V}) | &T V <- VERTICES );
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


public map[Node, list[Node]] createAdjacenciesMatrix(FlowGraph flowGraph) {
blockTree = ( origin: [] | <origin, _> <- flowGraph);

for(<origin, destination> <- flowGraph) {
blockTree[origin] = blockTree[origin] + [destination];
};

return blockTree;
}

public map[Node, list[Node]] createIdomTree(map[&T, set[&T]] dominanceTree) {
blockTree = ( treeKey: [] | treeKey <- dominanceTree);

for(treeKey <- dominanceTree) {
idom = findIdom(dominanceTree, treeKey);

if(treeKey != entryNode())
blockTree[idom] = blockTree[idom] + [treeKey];
};

return blockTree;
}

public Graph[&T] removeNodeFromGraph(Graph[&T] graph, &T nodeToRemove) {
return { <father, graphChild> | <father, graphChild> <- graph, nodeToRemove != father || nodeToRemove == entryNode() };
}

public Node computeDominator(FlowGraph flowGraph, Node currentNode) {
predecessorNodeList = [a | <a, b> <- flowGraph, b == currentNode];
result = if(isEmpty(predecessorNodeList) == true) currentNode; else head(predecessorNodeList);
return result;

public Node findIdom(map[&T, set[&T]] dominanceTree, Node child) {
ROOT = entryNode();
idom = entryNode();

possibleIdoms = [ father | father <- dominanceTree, child in dominanceTree[father] ];

for(possibleIdom <- possibleIdoms) {
if(size(dominanceTree[possibleIdom]) < size(dominanceTree[idom])) {
idom = possibleIdom;
};
};

return idom;
}
39 changes: 39 additions & 0 deletions src/main/rascal/lang/jimple/toolkit/ssa/Generator.rsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module lang::jimple::toolkit::ssa::Generator

import List;

import lang::jimple::toolkit::FlowGraph;
import lang::jimple::core::Syntax;

import lang::jimple::toolkit::ssa::DominanceTree;
import lang::jimple::toolkit::ssa::PhiFunctionInsertion;
import lang::jimple::toolkit::ssa::DominanceFrontier;
import lang::jimple::toolkit::ssa::VariableRenaming;

public FlowGraph applySSATransformation(MethodBody methodBody) {
FlowGraph flowGraph = forwardFlowGraph(methodBody);

if(hasUnsupportedInstruction(flowGraph)) // Doest not support invokeStmt and fieldRef rename
return {};

map[&T, set[&T]] dominanceTree = createDominanceTree(flowGraph);
map[&T, set[&T]] dominanceFrontier = createDominanceFrontier(flowGraph, dominanceTree);
FlowGraph phiFunctionFlowGraph = insertPhiFunctions(flowGraph, dominanceFrontier);
result = applyVariableRenaming(phiFunctionFlowGraph);
Copy link
Contributor Author

@mateusluizfb mateusluizfb Mar 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applies each SSA's stages


return result;
}

public bool hasUnsupportedInstruction(FlowGraph flowGraph) {
unsupportedList = [ <origin, destination> | <origin, destination> <- flowGraph, unspportedStatement(origin) || unspportedStatement(destination)];
return size(unsupportedList) != 0;
}
public bool unspportedStatement(Node nodeStatement) {
switch(nodeStatement) {
case stmtNode(invokeStmt(_)): return true;
case stmtNode(assign(fieldRef(_, _), _)): return true;
default: return false;
}
}
106 changes: 106 additions & 0 deletions src/main/rascal/lang/jimple/toolkit/ssa/PhiFunctionInsertion.rsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
module lang::jimple::toolkit::ssa::PhiFunctionInsertion

import demo::Dominators;
import Set;
import Relation;
import analysis::graphs::Graph;
import lang::jimple::toolkit::FlowGraph;
import lang::jimple::core::Syntax;
import Type;
import IO;
import Node;
import List;

public FlowGraph insertPhiFunctions(FlowGraph flowGraph, map[&T, set[&T]] dominanceFrontier) {
newFlowGraph = { <origin, destination> | <origin, destination> <- flowGraph };
variableList = { getStmtVariable(graphNode) | <graphNode, _> <- flowGraph, isVariable(graphNode) };
for(Variable variable <- variableList) {
F = {}; // set of basic blocks where φ is added
W = {}; // set of basic blocks that contain definitions of v
for(variableNode <- blocksWithVariable(flowGraph, variable)) { // d ∈ Defs(v)
B = variableNode;
W = W + {B};
};
while(size(W) != 0) {
// remove a basic block X from W
tuple[Node, set[Node]] elements = takeOneFrom(W);
X = elements[0];
W = elements[1];
if(X in dominanceFrontier) { // Avoids NoSuchKey error
frontierNodes = dominanceFrontier[X];
for(Y <- frontierNodes) { // Y : basic block ∈ DF(X )
if(size({Y} & F) == 0 && isJoinNode(flowGraph, Y)) { // Y \notin F && Y is a join node
newFlowGraph = insertPhiFunction(newFlowGraph, Y, variable); // add v←φ(...) at entry of Y
F = F + {Y}; // F ← F ∪ {Y}
if(size([Y] & blocksWithVariable(flowGraph, variable)) == 0) { // Y \notin Defs(v)
W = W + {Y}; // W ←W ∪{Y}
};
};
};
};
};
};
return newFlowGraph;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screen Shot 2021-03-23 at 20 08 47

public bool isJoinNode(FlowGraph flowGraph, Node frontierNode) {
int fathersSize = size([ fatherNode | <fatherNode, childNode> <- flowGraph, childNode == frontierNode ]);
return fathersSize > 1;
}
public &T getStmtVariable(Node graphNode) {
stmtNode(assignStatement) = graphNode;
variableArg = assignStatement[0];
return variableArg;
}
public list[Node] blocksWithVariable(FlowGraph flowGraph, Variable variable) {
return [graphNode | <graphNode, _> <- flowGraph, isSameVariable(graphNode, variable)];;
}
public bool isVariable(Node graphNode) {
if (size(graphNode[..]) == 0) return false;
stmtNode(assignStatement) = graphNode;
if (size(assignStatement[..]) == 0) return false;
variableArg = assignStatement[0];
typeOfVariableArg = typeOf(variableArg);
if (size(typeOfVariableArg[..]) == 0) return false;
return typeOfVariableArg.name == "Variable";
}
public bool isSameVariable(Node graphNode, Variable variable) {
if (size(graphNode[..]) == 0) return false;
stmtNode(assignStatement) = graphNode;
if (size(assignStatement[..]) == 0) return false;
variableArg = assignStatement[0];
typeOfVariableArg = typeOf(variableArg);
if (size(typeOfVariableArg[..]) == 0) return false;
return variableArg == variable;
}
public FlowGraph insertPhiFunction(FlowGraph flowGraph, Node childNode, Variable variable) {
fatherNodes = predecessors(flowGraph, childNode);
phiFunctionStmt = stmtNode(assign(variable, phiFunction(variable, [])));
phiFunctionRelations = { <fatherNode, phiFunctionStmt> | fatherNode <- fatherNodes };
filteredFlowGraph = { <origin, destination> | <origin, destination> <- flowGraph, !(origin in fatherNodes) || !(childNode == destination) };
flowGraphWithPhiFunction = phiFunctionRelations + filteredFlowGraph + {<phiFunctionStmt, childNode>};
return flowGraphWithPhiFunction;
}
Loading