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

soot.toolkits.graph.CytronDominanceFrontier 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.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Class to compute the DominanceFrontier using Cytron's celebrated efficient algorithm.
 *
 * @author Navindra Umanee
 * @see Efficiently Computing Static Single Assignment Form and
 *      the Control Dependence Graph
 **/
public class CytronDominanceFrontier implements DominanceFrontier {
  protected DominatorTree dt;
  protected Map, List>> nodeToFrontier;

  public CytronDominanceFrontier(DominatorTree dt) {
    this.dt = dt;
    nodeToFrontier = new HashMap, List>>();
    for (DominatorNode head : dt.getHeads()) {
      bottomUpDispatch(head);
    }
    for (N gode : dt.graph) {
      DominatorNode dode = dt.fetchDode(gode);
      if (dode == null) {
        throw new RuntimeException("dode == null");
      } else if (!isFrontierKnown(dode)) {
        System.out.print("'");
        System.out.print(dode);
        System.out.println("'");
        throw new RuntimeException("frontier did not have dode> ");
      }
    }
  }

  public List> getDominanceFrontierOf(DominatorNode node) {
    List> frontier = nodeToFrontier.get(node);
    if (frontier == null) {
      throw new RuntimeException("Frontier not defined for node: " + node);
    }
    return new ArrayList>(frontier);
  }

  protected boolean isFrontierKnown(DominatorNode node) {
    return nodeToFrontier.containsKey(node);
  }

  /**
   * Make sure we visit children first. This is reverse topological order.
   **/
  protected void bottomUpDispatch(DominatorNode node) {
    // *** FIXME: It's annoying that this algorithm is so
    // *** inefficient in that in traverses the tree from the head
    // *** to the tail before it does anything.

    if (isFrontierKnown(node)) {
      return;
    }

    for (DominatorNode child : dt.getChildrenOf(node)) {
      if (!isFrontierKnown(child)) {
        bottomUpDispatch(child);
      }
    }

    processNode(node);
  }

  /**
   * Calculate dominance frontier for a set of basic blocks.
   *
   * 

* Uses the algorithm of Cytron et al., TOPLAS Oct. 91: * *

   * for each X in a bottom-up traversal of the dominator tree do
   *
   *      DF(X) < - null
   *      for each Y in Succ(X) do
   *        if (idom(Y)!=X) then DF(X) <- DF(X) U Y
   *      end
   *      for each Z in {idom(z) = X} do
   *        for each Y in DF(Z) do
   *              if (idom(Y)!=X) then DF(X) <- DF(X) U Y
   *        end
   *      end
   * 
**/ protected void processNode(DominatorNode node) { List> dominanceFrontier = new ArrayList>(); // local { Iterator> succsIt = dt.getSuccsOf(node).iterator(); while (succsIt.hasNext()) { DominatorNode succ = succsIt.next(); if (!dt.isImmediateDominatorOf(node, succ)) { dominanceFrontier.add(succ); } } } // up { for (DominatorNode child : dt.getChildrenOf(node)) { for (DominatorNode childFront : getDominanceFrontierOf(child)) { if (!dt.isImmediateDominatorOf(node, childFront)) { dominanceFrontier.add(childFront); } } } } nodeToFrontier.put(node, dominanceFrontier); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy