Skip to content

Commit

Permalink
Merge 9148a0e into 06a2f63
Browse files Browse the repository at this point in the history
  • Loading branch information
wangzun66 authored Jan 16, 2025
2 parents 06a2f63 + 9148a0e commit bf02ba1
Show file tree
Hide file tree
Showing 28 changed files with 1,026 additions and 688 deletions.
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public Collection<Stmt> getNodes() {
@Nonnull
@Override
public List<? extends BasicBlock<?>> getBlocksSorted() {
return PostOrderBlockTraversal.getBlocksSorted(backingGraph);
PostOrderBlockTraversal traversal = new PostOrderBlockTraversal(backingGraph);
return traversal.getBlocksSorted();
}

@Nonnull
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
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;

/**
* This enum class is used to specify the direction of block analysis. Every enum direction name
* consists two parts: Block Order and Analysis Direction. eg: POSTORDERBACKWARD indicates that the
* sorted blocks are ordered in post-order(POSTORDER) and the analysis direction is from root to
* leaves (BACKWARD).
*/
public enum BlockAnalysisDirection {
POSTORDERBACKWARD {
@Override
@Nonnull
List<BasicBlock<?>> getPredecessors(BasicBlock<?> block) {
return (List<BasicBlock<?>>) block.getSuccessors();
}

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

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

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

@Nonnull
abstract List<BasicBlock<?>> getSortedBlocks(StmtGraph<?> blockGraph);
}
26 changes: 26 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,26 @@
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;

/** Interface of Block Iterator used to iterate each Block in a StmtGraph. */
public interface BlockIterator extends Iterator<BasicBlock<?>> {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
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.List;

/** An interface for defining a strategy to traverse a StmtGraph. */
public interface BlockTraversalStrategy {

/**
* This method provides an iterator to traverse a StmtGraph according to the defined strategy.
*
* @return an iterator for traversing StmtGraph
*/
public BlockIterator iterator();
/**
* This method returns a list of Blocks ordered by the traversal sequence.
*
* @return a list of Blocks in traversal order
*/
public List<BasicBlock<?>> getBlocksSorted();
}
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 @@ -26,7 +26,12 @@
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/*@author Zun Wang*/
/**
* This class is used to build a dominance tree for a BlockStmtGraph, which helps identify the
* dominator-relationships among blocks
*
* @see <a>https://en.wikipedia.org/wiki/Dominator_(graph_theory)</a>
*/
public class DominanceTree {

private List<BasicBlock<?>> blocks;
Expand All @@ -47,7 +52,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 @@ -49,6 +49,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 @@ -60,6 +60,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 @@ -24,6 +24,7 @@

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 @@ -486,7 +487,9 @@ public Set<? extends BasicBlock<?>> getBlocks() {

@Nonnull
public List<? extends BasicBlock<?>> getBlocksSorted() {
return ReversePostOrderBlockTraversal.getBlocksSorted(this);
ReversePostOrderBlockTraversal reversePostOrderBlockTraversal =
new ReversePostOrderBlockTraversal(this);
return reversePostOrderBlockTraversal.getBlocksSorted();
}

/**
Expand Down Expand Up @@ -1516,6 +1519,12 @@ public BasicBlock<?> getStartingStmtBlock() {
return getBlockOf(startingStmt);
}

@Override
@Nonnull
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

0 comments on commit bf02ba1

Please sign in to comment.