All Downloads are FREE. Search and download functionalities are using the official Maven repository.

soot.toolkits.graph.LoopNestTree Maven / Gradle / Ivy

There is a newer version: 1.12.0
Show newest version
/* Soot - a J*va Optimization Framework
 * Copyright (C) 2007 Eric Bodden
 *
 * This library 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 library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
package soot.toolkits.graph;

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 {

		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) {
		LoopFinder loopFinder = new LoopFinder();
		loopFinder.transform(b);
		
		Collection loops = loopFinder.loops();
		return loops;
	}
    
    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