Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

repair ssa #1104

Open
wants to merge 90 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
14e2594
correct spelling error
wangzun66 Oct 9, 2024
c9f8095
add interface BlockIterator
wangzun66 Oct 9, 2024
3fcafe0
add interface BlockTraversal
wangzun66 Oct 9, 2024
ea109c4
add test case and improve tests for BlockOrder
wangzun66 Oct 9, 2024
fda4bff
repair DominanceFinder
wangzun66 Oct 10, 2024
efed95b
test DominanceFinder
wangzun66 Oct 10, 2024
0a6c36c
remove redundant statements
wangzun66 Oct 10, 2024
9ef3cdf
recover analysis direction things
wangzun66 Oct 10, 2024
6024cd0
remove comment
wangzun66 Oct 16, 2024
d492acc
add test graph for PD
wangzun66 Oct 17, 2024
f1f3e63
add test case to check PD
wangzun66 Oct 17, 2024
61a9821
add function getTailBlocks in StmtGraph
wangzun66 Oct 17, 2024
a0d28e5
rename direction
wangzun66 Oct 17, 2024
45698f3
repair DominanceFinder
wangzun66 Oct 17, 2024
572bf45
repair tests for DominanceFinder
wangzun66 Oct 17, 2024
b791615
format
wangzun66 Oct 17, 2024
c225762
fix test
wangzun66 Oct 23, 2024
7184d00
fix DominanceTree
wangzun66 Oct 28, 2024
a99f775
build graph for SSA test
wangzun66 Oct 29, 2024
d8e2769
return a modified block and correct mergeable
wangzun66 Oct 30, 2024
907448a
fix ssa
wangzun66 Oct 30, 2024
09df251
fix ssa test_1
wangzun66 Oct 30, 2024
f9cfe32
update ssa_example
wangzun66 Oct 30, 2024
4a1107f
format
wangzun66 Oct 30, 2024
948da84
correct spelling error
wangzun66 Oct 9, 2024
1727220
add interface BlockIterator
wangzun66 Oct 9, 2024
307ce82
add interface BlockTraversal
wangzun66 Oct 9, 2024
dc127fb
add test case and improve tests for BlockOrder
wangzun66 Oct 9, 2024
6978cde
repair DominanceFinder
wangzun66 Oct 10, 2024
3104384
test DominanceFinder
wangzun66 Oct 10, 2024
7911217
remove redundant statements
wangzun66 Oct 10, 2024
6dec58e
recover analysis direction things
wangzun66 Oct 10, 2024
202a62c
remove comment
wangzun66 Oct 16, 2024
cf4fe00
add test graph for PD
wangzun66 Oct 17, 2024
0a7bc70
add test case to check PD
wangzun66 Oct 17, 2024
87a64ea
add function getTailBlocks in StmtGraph
wangzun66 Oct 17, 2024
ed2de20
rename direction
wangzun66 Oct 17, 2024
561555b
repair DominanceFinder
wangzun66 Oct 17, 2024
b781abf
repair tests for DominanceFinder
wangzun66 Oct 17, 2024
34900e8
format
wangzun66 Oct 17, 2024
f983d54
fix test
wangzun66 Oct 23, 2024
5247ffe
fix DominanceTree
wangzun66 Oct 28, 2024
9ad3f31
build graph for SSA test
wangzun66 Oct 29, 2024
eee584e
return a modified block and correct mergeable
wangzun66 Oct 30, 2024
584406c
fix ssa
wangzun66 Oct 30, 2024
3d2275a
fix ssa test_1
wangzun66 Oct 30, 2024
f7abe02
update ssa_example
wangzun66 Oct 30, 2024
a71cef4
format
wangzun66 Oct 30, 2024
1a9c236
Merge remote-tracking branch 'origin/ssa_correction' into ssa_correction
wangzun66 Oct 30, 2024
56a299d
build two new cases
wangzun66 Oct 31, 2024
93d368c
temporary update
wangzun66 Nov 5, 2024
790ff76
fix ssa with trap
wangzun66 Nov 5, 2024
dadb0af
disable two ssa test
wangzun66 Nov 5, 2024
b3d8250
change postorder blocks back
wangzun66 Nov 5, 2024
44e26a8
fix specified ssa case
wangzun66 Nov 6, 2024
8c5b7a1
disable wrong test in PostDominanceFinderTest
wangzun66 Nov 6, 2024
bec1fd8
correct spelling error
wangzun66 Oct 9, 2024
1f20d2f
add interface BlockIterator
wangzun66 Oct 9, 2024
756e170
add interface BlockTraversal
wangzun66 Oct 9, 2024
9445ef9
add test case and improve tests for BlockOrder
wangzun66 Oct 9, 2024
bff0a99
repair DominanceFinder
wangzun66 Oct 10, 2024
8390c97
test DominanceFinder
wangzun66 Oct 10, 2024
def7dbe
remove redundant statements
wangzun66 Oct 10, 2024
c045c33
recover analysis direction things
wangzun66 Oct 10, 2024
d2ea0b8
remove comment
wangzun66 Oct 16, 2024
409c06e
add test graph for PD
wangzun66 Oct 17, 2024
5ab0d93
add test case to check PD
wangzun66 Oct 17, 2024
c1de07d
add function getTailBlocks in StmtGraph
wangzun66 Oct 17, 2024
884a09b
rename direction
wangzun66 Oct 17, 2024
ec50155
repair DominanceFinder
wangzun66 Oct 17, 2024
fb4719c
repair tests for DominanceFinder
wangzun66 Oct 17, 2024
63c485e
format
wangzun66 Oct 17, 2024
332fb22
fix test
wangzun66 Oct 23, 2024
227ff03
fix DominanceTree
wangzun66 Oct 28, 2024
d5b5ae1
build graph for SSA test
wangzun66 Oct 29, 2024
31c7b54
return a modified block and correct mergeable
wangzun66 Oct 30, 2024
8814dd5
fix ssa
wangzun66 Oct 30, 2024
3f6a982
fix ssa test_1
wangzun66 Oct 30, 2024
cb0db69
update ssa_example
wangzun66 Oct 30, 2024
3145909
format
wangzun66 Oct 30, 2024
3feaa44
build two new cases
wangzun66 Oct 31, 2024
d6ce80a
temporary update
wangzun66 Nov 5, 2024
d940a2d
fix ssa with trap
wangzun66 Nov 5, 2024
ddda99c
disable two ssa test
wangzun66 Nov 5, 2024
ccf9edb
change postorder blocks back
wangzun66 Nov 5, 2024
25728cf
fix specified ssa case
wangzun66 Nov 6, 2024
23f04db
disable wrong test in PostDominanceFinderTest
wangzun66 Nov 6, 2024
9d66586
Merge remote-tracking branch 'origin/ssa_correction' into ssa_correction
wangzun66 Nov 6, 2024
07ada72
fmt
wangzun66 Nov 6, 2024
ab7df25
Merge branch 'develop' into ssa_correction
swissiety Nov 6, 2024
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
Binary file removed docs/assets/figures/SSA Example_1.png
Binary file not shown.
Binary file removed docs/assets/figures/SSA Example_2.png
Binary file not shown.
Binary file added docs/assets/figures/SSA_Example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shared-test-resources/bugfixes/ForLoopSSA.class
Binary file not shown.
9 changes: 9 additions & 0 deletions shared-test-resources/bugfixes/ForLoopSSA.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class ForLoopSSA {
public static void main(String[] args) {
String input = "";
for (int i = 0; i < args.length; i++) {
input = input + args[i];
}
System.out.println(input);
}
}
Binary file added shared-test-resources/bugfixes/TrapSSA.class
Binary file not shown.
11 changes: 11 additions & 0 deletions shared-test-resources/bugfixes/TrapSSA.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import java.io.*;
class TrapSSA {
public static void main(String[] args) throws IOException {
byte[] data;
try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
output.write(args[0].getBytes("UTF-8"));
data = output.toByteArray();
}
System.out.println(new String(data, "UTF-8"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package sootup.core.graph;
/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 2024 Junjie Shen
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
* #L%
*/

import java.util.Collections;
import java.util.List;
import javax.annotation.Nonnull;

public enum BlockAnalysisDirection {
POSTORDERBACKWARD {
@Override
@Nonnull
List<BasicBlock<?>> getPredecessors(BasicBlock<?> block) {
// todo: Blocks in PostOrderBackward contain no exceptional blocks!!
return (List<BasicBlock<?>>) block.getSuccessors();
}

@Nonnull
@Override
List<BasicBlock<?>> getSortedBlocks(StmtGraph<?> blockGraph) {
return Collections.unmodifiableList(PostOrderBlockTraversal.getBlocksSorted(blockGraph));
}
},
REVERSEPOSTORDERFORWARD {
@Override
@Nonnull
List<BasicBlock<?>> getPredecessors(BasicBlock<?> block) {
return (List<BasicBlock<?>>) block.getPredecessors();
}

@Nonnull
@Override
List<BasicBlock<?>> getSortedBlocks(StmtGraph<?> blockGraph) {
return Collections.unmodifiableList(
ReversePostOrderBlockTraversal.getBlocksSorted(blockGraph));
}
};

@Nonnull
abstract List<BasicBlock<?>> getPredecessors(BasicBlock<?> block);

@Nonnull
abstract List<BasicBlock<?>> getSortedBlocks(StmtGraph<?> blockGraph);
}
25 changes: 25 additions & 0 deletions sootup.core/src/main/java/sootup/core/graph/BlockIterator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package sootup.core.graph;
/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 2024 Junjie Shen
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
* #L%
*/
import java.util.Iterator;

public interface BlockIterator extends Iterator<BasicBlock<?>> {}
23 changes: 23 additions & 0 deletions sootup.core/src/main/java/sootup/core/graph/BlockTraversal.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package sootup.core.graph;
/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 2024 Junjie Shen
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
* #L%
*/
public interface BlockTraversal {}
91 changes: 36 additions & 55 deletions sootup.core/src/main/java/sootup/core/graph/DominanceFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,78 +24,55 @@

import java.util.*;
import javax.annotation.Nonnull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @author Zun Wang
* @see <a
* href="https://www.researchgate.net/publication/2569680_A_Simple_Fast_Dominance_Algorithm">
* https://www.researchgate.net/publication/2569680_A_Simple_Fast_Dominance_Algorithm </a>
*/
public class DominanceFinder {

private static Logger LOGGER = LoggerFactory.getLogger(DominanceFinder.class);

private List<BasicBlock<?>> blocks;
private Map<BasicBlock<?>, Integer> blockToIdx = new HashMap<>();
private int[] doms;
private ArrayList<Integer>[] domFrontiers;
private BlockAnalysisDirection direction;

protected AnalysisDirection direction;

public enum AnalysisDirection {
BACKWARD {
@Override
@Nonnull
List<? extends BasicBlock<?>> getPredecessors(BasicBlock<?> block) {
return block.getSuccessors();
}

@Nonnull
@Override
List<BasicBlock<?>> getSortedBlocks(StmtGraph<?> blockGraph) {
return Collections.unmodifiableList(new BackwardsStmtGraph(blockGraph).getBlocksSorted());
}
},
FORWARD {
@Override
@Nonnull
List<? extends BasicBlock<?>> getPredecessors(BasicBlock<?> block) {
return block.getPredecessors();
}

@Nonnull
@Override
List<BasicBlock<?>> getSortedBlocks(StmtGraph<?> blockGraph) {
return Collections.unmodifiableList(blockGraph.getBlocksSorted());
}
};

@Nonnull
abstract List<? extends BasicBlock<?>> getPredecessors(BasicBlock<?> block);

@Nonnull
abstract List<BasicBlock<?>> getSortedBlocks(StmtGraph<?> blockGraph);
public DominanceFinder(StmtGraph<?> blockGraph) {
// normal DominanceFinder should be in reverse post order
this(blockGraph, BlockAnalysisDirection.REVERSEPOSTORDERFORWARD);
}

public DominanceFinder(@Nonnull StmtGraph<?> blockGraph) {
this(blockGraph, AnalysisDirection.FORWARD);
}
protected DominanceFinder(@Nonnull StmtGraph<?> blockGraph, BlockAnalysisDirection direction) {

protected DominanceFinder(@Nonnull StmtGraph<?> blockGraph, AnalysisDirection direction) {
// define the blocks' order
this.direction = direction;

// we're locked into providing a List<BasicBlock<?>>, not a List<? extends BasicBlock<?>>, so
// we'll use the block iterator directly (which provides this type) rather than
// #getBlocksSorted.
blocks = direction.getSortedBlocks(blockGraph);

// assign each block a integer id. The starting block must have id 0; rely on
// getBlocksSorted to have put the starting block first.
for (int i = 0; i < blocks.size(); i++) {
BasicBlock<?> block = blocks.get(i);
blockToIdx.put(block, i);
}
final BasicBlock<?> startingStmtBlock = blocks.get(0);

// initialize doms
final BasicBlock<?> startBlock;
if (direction == BlockAnalysisDirection.REVERSEPOSTORDERFORWARD
|| direction == BlockAnalysisDirection.POSTORDERBACKWARD) {
startBlock = blocks.get(0);
if (direction == BlockAnalysisDirection.POSTORDERBACKWARD) {
// todo: Postdominantor (POSTORDERBACKWARD) doesn't work for with multiple tail-blocks.
List<BasicBlock<?>> tails = blockGraph.getTailStmtBlocks();
if (tails.size() > 1) {
LOGGER.warn(
"BlockGraph has multiple tail-blocks, the Post-Dominators Computation could be incorrect!");
}
}
} else {
throw new RuntimeException("Invalid BlockAnalysisDirection!");
}
doms = new int[blocks.size()];
Arrays.fill(doms, -1);
doms[0] = 0;
Expand All @@ -105,12 +82,11 @@ protected DominanceFinder(@Nonnull StmtGraph<?> blockGraph, AnalysisDirection di
while (isChanged) {
isChanged = false;
for (BasicBlock<?> block : blocks) {
if (block.equals(startingStmtBlock)) {
if (block.equals(startBlock)) {
continue;
}
int blockIdx = blockToIdx.get(block);
List<BasicBlock<?>> preds = new ArrayList<>(direction.getPredecessors(block));
// ms: should not be necessary preds.addAll(block.getExceptionalPredecessors());
int newIdom = getFirstDefinedBlockPredIdx(preds);
if (!preds.isEmpty() && newIdom != -1) {
BasicBlock<?> processed = blocks.get(newIdom);
Expand All @@ -131,19 +107,16 @@ protected DominanceFinder(@Nonnull StmtGraph<?> blockGraph, AnalysisDirection di
}
}

// startBlockId should not have immediate dominator, actually.
doms[0] = -1;

// initialize domFrontiers
domFrontiers = new ArrayList[blockGraph.getBlocks().size()];
domFrontiers = new ArrayList[blocks.size()];
for (int i = 0; i < domFrontiers.length; i++) {
domFrontiers[i] = new ArrayList<>();
}

doms[0] = -1;
// calculate dominance frontiers for each block
for (BasicBlock<?> block : blocks) {
List<BasicBlock<?>> preds = new ArrayList<>(direction.getPredecessors(block));
// ms: should not be necessary preds.addAll(block.getExceptionalPredecessors());
if (preds.size() > 1) {
int blockId = blockToIdx.get(block);
for (BasicBlock<?> pred : preds) {
Expand All @@ -155,6 +128,14 @@ protected DominanceFinder(@Nonnull StmtGraph<?> blockGraph, AnalysisDirection di
}
}
}

if (direction == BlockAnalysisDirection.POSTORDERBACKWARD) {
for (int i = 0; i < domFrontiers.length; i++) {
if (domFrontiers[i].contains(i)) {
domFrontiers[i].remove(new Integer(i));
}
}
}
}

public void replaceBlock(@Nonnull BasicBlock<?> newBlock, BasicBlock<?> oldBlock) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public DominanceTree(@Nonnull DominanceFinder dominanceFinder) {
}

for (int i = 0; i < treeSize; i++) {
if (iDoms[i] != i) {
if (iDoms[i] != -1 && iDoms[i] != i) {
parents[i] = iDoms[i];
children[iDoms[i]].add(i);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ public BasicBlock<?> getStartingStmtBlock() {
return backingGraph.getStartingStmtBlock();
}

@Override
public List<BasicBlock<?>> getTailStmtBlocks() {
return backingGraph.getTailStmtBlocks();
}

@Override
public BasicBlock<?> getBlockOf(@Nonnull Stmt stmt) {
return backingGraph.getBlockOf(stmt);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ public BasicBlock<?> getStartingStmtBlock() {
throw new UnsupportedOperationException("Not implemented yet!");
}

@Override
public List<BasicBlock<?>> getTailStmtBlocks() {
throw new UnsupportedOperationException("Not implemented yet!");
}

@Override
public BasicBlock<ImmutableBasicBlock> getBlockOf(@Nonnull Stmt stmt) {
throw new UnsupportedOperationException("Not implemented yet!");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Lists;
import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.MutablePair;
Expand Down Expand Up @@ -789,7 +790,8 @@ protected boolean isMergeable(
}
// if we are here the datastructure should have managed that the next if is true..
final List<MutableBasicBlock> sBlockPredecessors = followingBlock.getPredecessors();
if (sBlockPredecessors.size() != 1 || sBlockPredecessors.get(0) != firstBlock) {
if (sBlockPredecessors.size() > 1
|| (sBlockPredecessors.size() == 1 && sBlockPredecessors.get(0) != firstBlock)) {
return false;
}
// check if the same traps are applied to both blocks
Expand Down Expand Up @@ -1072,12 +1074,12 @@ public void validateBlocks() {
* simplifies the handling of BranchingStmts)
* @param stmts
*/
public void insertBefore(
public BasicBlock<?> insertBefore(
@Nonnull Stmt beforeStmt,
@Nonnull List<FallsThroughStmt> stmts,
@Nonnull Map<ClassType, Stmt> exceptionMap) {
if (stmts.isEmpty()) {
return;
return stmtToBlock.get(beforeStmt).getRight();
}
final Pair<Integer, MutableBasicBlock> beforeStmtBlockPair = stmtToBlock.get(beforeStmt);
if (beforeStmtBlockPair == null) {
Expand All @@ -1100,7 +1102,8 @@ public void insertBefore(
// all inserted Stmts are FallingThrough: so successorIdx = 0
predecessorBlock.linkSuccessor(0, block);
}

checkAndResetStartingStmt(beforeStmt, stmts);
return predecessorBlock;
} else {
// TODO: check conditions before splitting if split will be necessary instead of
// split-and-merge
Expand All @@ -1124,8 +1127,12 @@ public void insertBefore(
}
blocks.add(successorBlock);
}
checkAndResetStartingStmt(beforeStmt, stmts);
return block;
}
}

private void checkAndResetStartingStmt(Stmt beforeStmt, List<FallsThroughStmt> stmts) {
if (beforeStmt == getStartingStmt()) {
setStartingStmt(stmts.get(0));
}
Expand Down Expand Up @@ -1384,6 +1391,11 @@ public BasicBlock<?> getStartingStmtBlock() {
return getBlockOf(startingStmt);
}

@Override
public List<BasicBlock<?>> getTailStmtBlocks() {
return getTails().stream().map(stmt -> getBlockOf(stmt)).collect(Collectors.toList());
}

@Override
@Nullable
public BasicBlock<?> getBlockOf(@Nonnull Stmt stmt) {
Expand Down
Loading
Loading