soot.toolkits.graph.LoopNestTree Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of soot Show documentation
Show all versions of soot Show documentation
A Java Optimization Framework
The newest version!
package soot.toolkits.graph;
/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 2007 Eric Bodden
* %%
* 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
* .
* #L%
*/
import java.util.Collection;
import java.util.Comparator;
import java.util.TreeSet;
import soot.Body;
import soot.jimple.Stmt;
import soot.jimple.toolkits.annotation.logic.Loop;
import soot.jimple.toolkits.annotation.logic.LoopFinder;
/**
* A loop nesting tree, implemented as a tree-map. Loops are represented by pairs of head-statements and the respective loop.
* The iterator over this collection returns the loop in such an order that a loop l will always returned before a loop m if
* l is an inner loop of m.
*
* @author Eric Bodden
*/
public class LoopNestTree extends TreeSet {
/**
* Comparator, stating that a loop l1 is smaller than a loop l2 if l2 contains all statements of l1.
*
* @author Eric Bodden
*/
private static class LoopNestTreeComparator implements Comparator {
@Override
public int compare(Loop loop1, Loop loop2) {
Collection stmts1 = loop1.getLoopStatements();
Collection stmts2 = loop2.getLoopStatements();
if (stmts1.equals(stmts2)) {
assert loop1.getHead().equals(loop2.getHead()); // should really have the same head then
// equal (same) loops
return 0;
} else if (stmts1.containsAll(stmts2)) {
// 1 superset of 2
return 1;
} else if (stmts2.containsAll(stmts1)) {
// 1 subset of 2
return -1;
}
// overlap (?) or disjoint: order does not matter;
// however we must *not* return 0 as this would only keep one of the two loops;
// hence, return 1
return 1;
}
}
/**
* Builds a loop nest tree from a method body using {@link LoopFinder}.
*/
public LoopNestTree(Body b) {
this(computeLoops(b));
}
/**
* Builds a loop nest tree from a mapping from loop headers to statements in the loop.
*/
public LoopNestTree(Collection loops) {
super(new LoopNestTreeComparator());
addAll(loops);
}
private static Collection computeLoops(Body b) {
return new LoopFinder().getLoops(b);
}
public boolean hasNestedLoops() {
// TODO could be speeded up by just comparing two consecutive
// loops returned by the iterator
LoopNestTreeComparator comp = new LoopNestTreeComparator();
for (Loop loop1 : this) {
for (Loop loop2 : this) {
if (comp.compare(loop1, loop2) != 0) {
return true;
}
}
}
return false;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy