ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
dominatorTreesAndDominanceFrontiers/SimpleDirectedGraph.h
Go to the documentation of this file.
1 #ifndef _SIMPLE_DIRECTED_GRAPH_H_
2 #define _SIMPLE_DIRECTED_GRAPH_H_
3 
4 #include <iostream>
5 #include <fstream>
6 #include <set>
7 #include <map>
8 #include <stack>
9 
10 // DQ (12/30/2005): This is a Bad Bad thing to do (I can explain)
11 // it hides names in the global namespace and causes errors in
12 // otherwise valid and useful code. Where it is needed it should
13 // appear only in *.C files (and only ones not included for template
14 // instantiation reasons) else they effect user who use ROSE unexpectedly.
15 // using namespace std;
16 
28 
29 
30 public:
31 
33 
35  std::set<SimpleDirectedGraphNode *> getSuccessors() {return _succs;}
37  std::set<SimpleDirectedGraphNode *> getPredecessors() {return _preds;}
38 
43 
45  bool hasSuccessor(SimpleDirectedGraphNode * n) {return _succs.count(n) != 0;}
47  bool hasPredecessor(SimpleDirectedGraphNode * n) {return _preds.count(n) != 0;}
48 
50  int numSuccessors() {return _succs.size();}
52  int numPredecessors() {return _preds.size();}
53 
55  virtual void writeOut(std::ostream & os) {
56  char buf[sizeof(SimpleDirectedGraphNode *)*2 + 3];
57  sprintf(buf, "%p", this);
58  os << buf;
59  }
60 
61  private:
62 
64  std::set<SimpleDirectedGraphNode *> _succs;
66  std::set<SimpleDirectedGraphNode *> _preds;
67 
68 };
69 
70 
79 
80 public:
81 
83 
85  std::set<SimpleDirectedGraphNode *> getNodes() {return _nodes;}
86 
88  virtual void addNode(SimpleDirectedGraphNode * node) {
89  _nodes.insert(node);
90  }
91 
94 
95  // Add "to" to the successors of "from" and "from" to the
96  // predecessors of "to" to initialize the edge in the graph
97  from->addSuccessor(to);
98  to->addPredecessor(from);
99  }
100 
103  return _nodes.count(node) > 0;
104  }
105 
108  return from->hasSuccessor(to);
109  }
110 
111  void printGraph() {
112  std::set<SimpleDirectedGraphNode *>::iterator i;
113  for (i = _nodes.begin(); i != _nodes.end(); i++) {
114  _displayData(*i, std::cout);
115  std::cout << ":" << std::endl;
116  std::set<SimpleDirectedGraphNode *> succs = (*i)->getSuccessors();
117  std::set<SimpleDirectedGraphNode *>::iterator j;
118  for (j = succs.begin(); j != succs.end(); j++) {
119  std::cout << " succ: ";
120  _displayData(*j, std::cout);
121  std::cout << std::endl;
122  }
123  std::set<SimpleDirectedGraphNode *> preds = (*i)->getPredecessors();
124  for (j = preds.begin(); j != preds.end(); j++) {
125  std::cout << " pred: ";
126  _displayData(*j, std::cout);
127  std::cout << std::endl;
128  }
129  std::cout << std::endl;
130  }
131  }
132 
133  virtual void writeDot(char * filename) {
134 
135  std::ofstream f(filename);
136 
137  f << "digraph \"G" << filename << "\" {" << std::endl;
138  //output all of the nodes
139  std::set<SimpleDirectedGraphNode *>::iterator i;
140  for (i = _nodes.begin(); i != _nodes.end(); i++) {
141  SimpleDirectedGraphNode * d = *i;
142  char buf[sizeof(SimpleDirectedGraphNode *)*2 + 3];
143  sprintf(buf, "%p", d);
144  f << "\"" << buf << "\" [label = \"";
145  _displayData(d, f);
146  f << "\"];" << std::endl;
147  }
148 
149  //output all of the edges (we'll just use successor edges
150  for (i = _nodes.begin(); i != _nodes.end(); i++) {
151  SimpleDirectedGraphNode * d1 = *i;
152  std::set<SimpleDirectedGraphNode *> succs = d1->getSuccessors();
153  std::set<SimpleDirectedGraphNode *>::iterator j;
154  for (j = succs.begin(); j != succs.end(); j++) {
155  SimpleDirectedGraphNode * d2 = *j;
156 
157  char buf1[sizeof(SimpleDirectedGraphNode *)*2 + 3];
158  char buf2[sizeof(SimpleDirectedGraphNode *)*2 + 3];
159 
160  sprintf(buf1, "%p", d1);
161  sprintf(buf2, "%p", d2);
162 
163  f << "\"" << buf1 << "\" -> \"" << buf2 << "\";" << std::endl;
164  }
165  }
166 
167  f << "}" << std::endl;
168  }
169 
174  enum TraverseDirection // NO_STRINGIFY
175  {
176  FORWARD = 1,
177  BACKWARD = 2
178  };
179 
180  std::set<SimpleDirectedGraphNode *> getReachable(SimpleDirectedGraphNode * start, TraverseDirection dir) {
181 
182  std::set<SimpleDirectedGraphNode *> reachables;
183  std::stack<SimpleDirectedGraphNode *> remaining;
184 
185  remaining.push(start);
186 
187  //Simple DFS on graph to find reachable nodes
188  while (remaining.size() != 0) {
189  //Get the first node on the stack
190  SimpleDirectedGraphNode * curr = remaining.top();
191  remaining.pop();
192 
193  //if we haven't already seen it, add it to our return list, and
194  //push its children onto the stack
195  if (reachables.count(curr) == 0) {
196  reachables.insert(curr);
197 
198  //depending on TraverseDirection, children should either be
199  //the successors or predecessors of curr
200  std::set<SimpleDirectedGraphNode *> children;
201  switch(dir) {
202  case FORWARD:
203  children = curr->getSuccessors();
204  break;
205  case BACKWARD:
206  children = curr->getPredecessors();
207  break;
208  default:
209  //This should never happen
210  abort();
211  break;
212  }
213 
214  //push the children onto the stack
215  std::set<SimpleDirectedGraphNode *>::iterator i;
216  for (i = children.begin(); i != children.end(); i++) {
217  remaining.push(*i);
218  }
219  } else {
220  //Do nothing - we've already seen this node
221  }
222  }
223 
224  return reachables;
225  }
226 
227 protected:
228 
233  virtual void _displayData(SimpleDirectedGraphNode * node, std::ostream & os) {
234  node->writeOut(os);
235  }
236 
237  std::set<SimpleDirectedGraphNode *> _nodes;
238 
239 };
240 
241 #endif