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

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

package soot.toolkits.graph;

/*-
 * #%L
 * Soot - a J*va Optimization Framework
 * %%
 * Copyright (C) 2003 Navindra Umanee 
 * %%
 * 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.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import soot.toolkits.scalar.ArrayPackedSet;
import soot.toolkits.scalar.BoundedFlowSet;
import soot.toolkits.scalar.CollectionFlowUniverse;
import soot.toolkits.scalar.FlowSet;
import soot.toolkits.scalar.FlowUniverse;
import soot.toolkits.scalar.ForwardFlowAnalysis;

/**
 * Wrapper class for a simple dominators analysis based on a simple flow analysis algorithm. Works with any DirectedGraph
 * with a single head.
 *
 * @author Navindra Umanee
 **/
public class SimpleDominatorsFinder implements DominatorsFinder {
  private static final Logger logger = LoggerFactory.getLogger(SimpleDominatorsFinder.class);
  protected DirectedGraph graph;
  protected Map> nodeToDominators;

  /**
   * Compute dominators for provided singled-headed directed graph.
   **/
  public SimpleDominatorsFinder(DirectedGraph graph) {
    // if(Options.v().verbose())
    // logger.debug("[" + graph.getBody().getMethod().getName() +
    // "] Finding Dominators...");

    this.graph = graph;
    SimpleDominatorsAnalysis analysis = new SimpleDominatorsAnalysis(graph);

    // build node to dominators map
    {
      nodeToDominators = new HashMap>(graph.size() * 2 + 1, 0.7f);

      for (Iterator nodeIt = graph.iterator(); nodeIt.hasNext();) {
        N node = nodeIt.next();
        FlowSet set = analysis.getFlowAfter(node);
        nodeToDominators.put(node, set);
      }
    }
  }

  public DirectedGraph getGraph() {
    return graph;
  }

  public List getDominators(N node) {
    // non-backed list since FlowSet is an ArrayPackedFlowSet
    return nodeToDominators.get(node).toList();
  }

  public N getImmediateDominator(N node) {
    // root node
    if (getGraph().getHeads().contains(node)) {
      return null;
    }

    // avoid the creation of temp-lists
    FlowSet head = (FlowSet) nodeToDominators.get(node).clone();
    head.remove(node);

    for (N dominator : head) {
      if (nodeToDominators.get(dominator).isSubSet(head)) {
        return dominator;
      }
    }

    return null;
  }

  public boolean isDominatedBy(N node, N dominator) {
    // avoid the creation of temp-lists
    return nodeToDominators.get(node).contains(dominator);
  }

  public boolean isDominatedByAll(N node, Collection dominators) {
    FlowSet f = nodeToDominators.get(node);
    for (N n : dominators) {
      if (!f.contains(n)) {
        return false;
      }
    }
    return true;
  }
}

/**
 * Calculate dominators for basic blocks.
 * 

* Uses the algorithm contained in Dragon book, pg. 670-1. * *

 *       D(n0) := { n0 }
 *       for n in N - { n0 } do D(n) := N;
 *       while changes to any D(n) occur do
 *         for n in N - {n0} do
 *             D(n) := {n} U (intersect of D(p) over all predecessors p of n)
 * 
**/ class SimpleDominatorsAnalysis extends ForwardFlowAnalysis> { private FlowSet emptySet; private BoundedFlowSet fullSet; SimpleDominatorsAnalysis(DirectedGraph graph) { super(graph); // define empty set, with proper universe for complementation List nodes = new ArrayList(graph.size()); for (N n : graph) { nodes.add(n); } FlowUniverse nodeUniverse = new CollectionFlowUniverse(nodes); emptySet = new ArrayPackedSet(nodeUniverse); fullSet = (BoundedFlowSet) emptySet.clone(); fullSet.complement(); doAnalysis(); } /** * All OUTs are initialized to the full set of definitions OUT(Start) is tweaked in customizeInitialFlowGraph. **/ @Override protected FlowSet newInitialFlow() { return (FlowSet) fullSet.clone(); } /** * OUT(Start) contains all head nodes at initialization time. **/ @Override protected FlowSet entryInitialFlow() { FlowSet initSet = (FlowSet) emptySet.clone(); for (N h : graph.getHeads()) { initSet.add(h); } return initSet; } /** * We compute out straightforwardly. **/ @Override protected void flowThrough(FlowSet in, N block, FlowSet out) { // Perform generation in.copy(out); out.add(block); } /** * All paths == Intersection. **/ @Override protected void merge(FlowSet in1, FlowSet in2, FlowSet out) { in1.intersection(in2, out); } @Override protected void mergeInto(N block, FlowSet inout, FlowSet in) { inout.intersection(in); } @Override protected void copy(FlowSet source, FlowSet dest) { source.copy(dest); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy