DomTree.cpp

Go to the documentation of this file.
00001 
00017 //---------------------------------------------------------------------------
00018 
00019 // OpenAnalysis headers
00020 #include "DomTree.hpp"
00021 
00022 #include <iostream>
00023 using std::ostream;
00024 using std::endl;
00025 
00026 // STL headers
00027 #include <algorithm>
00028 #include <vector>
00029 
00030 //---------------------------------------------------------------------------
00031 
00032 namespace OA {
00033 
00034 //***************************************************************************
00035 // 
00036 //***************************************************************************
00037 
00050 DomTree::DomTree(OA_ptr<DGraph::DGraphInterface> graph_)
00051   : Tree(), graph(graph_)
00052 {
00053   int i;
00054 
00055   // first, populate the tree with nodes corresponding to the directed
00056   // graph g and number them for easy reference
00057   int S = graph->getNumNodes();
00058   std::vector<OA_ptr<Node> > tree_node_vec(S);
00059   std::vector<OA_ptr<DGraph::NodeInterface> > graph_node_vec(S);
00060   std::vector<std::set<int> > dom_set(S);
00061   std::map<OA_ptr<DGraph::NodeInterface>, int> graph_node_num;
00062   
00063   int count = 0;
00064   OA_ptr<DGraph::NodesIteratorInterface> dfs_iter = graph->getDFSIterator();
00065   for ( ; dfs_iter->isValid(); ++(*dfs_iter)) {
00066     OA_ptr<DGraph::NodeInterface> n = dfs_iter->current();
00067     tree_node_vec[count] = new Node(n);
00068     graph_node_vec[count] = n;
00069     graph_node_num[n] = count;
00070     dom_tree_node[n] = tree_node_vec[count];
00071     ++count;
00072   }
00073   addNode(tree_node_vec[0]); // add the root node
00074   dom_set[0].insert(1); // initialize the root node's dom set
00075   
00076   // now propagate the dominator sets for each node iteratively until
00077   // a fixed point is reached but, we do this only for nodes that are
00078   // actually reachable from the root ("count" nodes)
00079   bool changed = true;
00080   while (changed) {
00081     changed = false;
00082     std::set<int> tmp_dom;
00083     for (i=0; i < count; i++) {
00084       // intersect the dom sets of each of the predecessors
00085       tmp_dom.clear();
00086 
00087       OA_ptr<DGraph::NodesIteratorInterface> src_iter = 
00088         graph_node_vec[i]->getSourceNodesIterator();
00089       while (src_iter->isValid() && 
00090              dom_set[graph_node_num[src_iter->current()]].empty())
00091         ++(*src_iter);
00092       if (src_iter->isValid()) {
00093         int node_num = graph_node_num[src_iter->current()];
00094         tmp_dom = dom_set[node_num];
00095         ++(*src_iter);
00096       }
00097       while (src_iter->isValid()) {
00098         int node_num = graph_node_num[src_iter->current()];
00099         if (!dom_set[node_num].empty()) {
00100           std::set<int> tmp;
00101           std::set_intersection(tmp_dom.begin(), tmp_dom.end(), 
00102                                 dom_set[node_num].begin(), 
00103                                 dom_set[node_num].end(),
00104                                 std::inserter(tmp, tmp.begin()));
00105           tmp_dom = tmp;
00106         }
00107         ++(*src_iter);
00108       }
00109       tmp_dom.insert(i);
00110       if (!(tmp_dom == dom_set[i])) {
00111         changed = true;
00112         dom_set[i] = tmp_dom;
00113       }
00114     }
00115   }
00116 
00117   // finally, find the immediate dominator of each node and insert
00118   // appropriate edges
00119   for (i=0; i < count; i++) {
00120     std::set<int>::iterator ds_iter = dom_set[i].begin();
00121     int parent_of_i = -1;
00122     while (ds_iter != dom_set[i].end()) {
00123       int val = *ds_iter;
00124       if ((parent_of_i < val) && (val != i))
00125         parent_of_i = val;
00126       ++ds_iter;
00127     }
00128     if (parent_of_i >= 0) {
00129       OA_ptr<Edge> e; 
00130       e = new Edge(tree_node_vec[parent_of_i], tree_node_vec[i]);
00131       addEdge(e);
00132     }
00133   }
00134 
00135 }
00136 
00137 
00157 void
00158 DomTree::compute_dominance_frontiers ()
00159 {
00160   OA_ptr<DGraph::NodesIteratorInterface> nodes_iter = 
00161     graph->getNodesIterator();
00162   while (nodes_iter->isValid()) {
00163     OA_ptr<DGraph::NodeInterface> b = nodes_iter->current();
00164     if (b->num_incoming() > 1) {
00165       OA_ptr<DGraph::NodesIteratorInterface> p = 
00166         b->getSourceNodesIterator();
00167       while (p->isValid()) {
00168         OA_ptr<DGraph::NodeInterface> runner = p->current();
00169         // this parent may be unreachable in the control flow graph and, hence, may have no corresponding Dominator
00170         // Tree node
00171         if (dom_tree_node.find(runner) != dom_tree_node.end()) {
00172           OA_ptr<Node> b_dom_tree_node = dom_tree_node[b];
00173           OA_ptr<Node> runner_dom_tree_node = dom_tree_node[runner];
00174           while (runner_dom_tree_node != b_dom_tree_node->parent()) {
00175             if (runner_dom_tree_node->dom_front.find(b_dom_tree_node) == 
00176                 runner_dom_tree_node->dom_front.end()) {
00177               runner_dom_tree_node->dom_front.insert(b_dom_tree_node);
00178             }
00179             OA_ptr<Node> n = runner_dom_tree_node->parent();
00180             runner = n->graph_node_ptr;
00181             runner_dom_tree_node = dom_tree_node[runner];
00182           }
00183         }
00184         ++(*p);
00185       }
00186     }
00187     ++(*nodes_iter);
00188   }
00189 }
00190 
00191 
00192 void
00193 DomTree::dump (ostream& os)
00194 {
00195   OA_ptr<NodesIterator> nodes_iter = getNodesIterator();
00196   while (nodes_iter->isValid()) {
00197     OA_ptr<Tree::Node> treenode = nodes_iter->current();
00198     OA_ptr<Node> n = treenode.convert<Node>();
00199     os << "[";
00200     if (!n->parent().ptrEqual(0)) {
00201       OA_ptr<Node> n1 = n->parent();
00202       n1->graph_node_ptr->dumpbase(os);
00203     }
00204     else {
00205       os << "root";
00206     }
00207     os << "] --> ";
00208     n->graph_node_ptr->dumpbase(os);
00209     os << " --> {";
00210     OA_ptr<ChildNodesIterator> child_iter = n->getChildNodesIterator();
00211     if (child_iter->isValid()) {
00212       OA_ptr<Tree::Node> n = child_iter->current();
00213       OA_ptr<Node> n1 = n.convert<Node>();
00214       n1->graph_node_ptr->dumpbase(os);
00215       ++(*child_iter);
00216       for ( ; child_iter->isValid(); ++(*child_iter)) {
00217         OA_ptr<Tree::Node> n = child_iter->current();
00218         OA_ptr<Node> n1 = n.convert<Node>();
00219         os << ", ";
00220         n1->graph_node_ptr->dumpbase(os);
00221       }
00222     }
00223     os << "}  DF = {";
00224     OA_ptr<DomFrontIterator> front_iter = n->getDomFrontIterator();
00225     if (front_iter->isValid()) {
00226       front_iter->current()->dump(os);
00227       ++(*front_iter);
00228       for ( ; front_iter->isValid(); ++(*front_iter)) {
00229         os << ", ";
00230         front_iter->current()->dump(os);
00231       }
00232     }
00233     os << "}" << endl;
00234     ++(*nodes_iter);
00235   }
00236 }
00237 
00238 
00239 //***************************************************************************
00240 // 
00241 //***************************************************************************
00242 
00243 void 
00244 DomTree::Node::dump(std::ostream& os)
00245 {
00246   OA_ptr<DGraph::NodeInterface> n = getGraphNode();
00247   n->dumpbase(os);
00248   
00249   DomFrontSet::iterator it = dom_front.begin();
00250   for ( ; it != dom_front.end(); ++it) {
00251     OA_ptr<Node> n = *it;
00252     os << "<treenode> ";
00253   }
00254 }
00255 
00256 
00257 } // end of namespace OA
00258