5 #include <boost/graph/adjacency_list.hpp>
6 #include <boost/bind.hpp>
7 #include <boost/foreach.hpp>
8 #include <boost/tuple/tuple.hpp>
9 #include <boost/graph/graphviz.hpp>
10 #include <boost/graph/dominator_tree.hpp>
11 #include <boost/graph/reverse_graph.hpp>
12 #include <boost/graph/transpose_graph.hpp>
13 #include <boost/algorithm/string.hpp>
19 template <
class CFGNodeT,
class CFGEdgeT>
20 class CFG :
public boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS,
21 boost::shared_ptr<CFGNodeT>, boost::shared_ptr<CFGEdgeT> >
24 typedef typename boost::graph_traits<CFG<CFGNodeT, CFGEdgeT> >
GraphTraits;
33 typedef typename GraphTraits::vertex_descriptor
Vertex;
34 typedef typename GraphTraits::edge_descriptor
Edge;
122 std::map<CFGNodeType, Vertex>& nodesAdded,
123 std::set<CFGNodeType>& nodesProcessed);
159 template <
class CFGNodeT,
class CFGEdgeT>
162 ROSE_ASSERT(funcDef);
166 nodesToVertices_.clear();
167 std::set<CFGNodeType> nodesProcessed;
171 entry_ = GraphTraits::null_vertex();
172 exit_ = GraphTraits::null_vertex();
183 template <
class CFGNodeT,
class CFGEdgeT>
186 BOOST_FOREACH (
Vertex v, boost::vertices(*
this))
191 if (node->getIndex() == 0)
193 else if (node->getIndex() == 3)
200 if (exit_ == GraphTraits::null_vertex())
202 std::cerr <<
"This function may contain an infinite loop "
203 "inside so that its CFG cannot be built" << std::endl;
204 exit_ = add_vertex(*
this);
208 ROSE_ASSERT(entry_ != GraphTraits::null_vertex());
209 ROSE_ASSERT(exit_ != GraphTraits::null_vertex());
212 template <
class CFGNodeT,
class CFGEdgeT>
215 std::map<CFGNodeType, Vertex>& nodesAdded,
216 std::set<CFGNodeType>& nodesProcessed)
218 ROSE_ASSERT(node.getNode());
220 if (nodesProcessed.count(node) > 0)
222 nodesProcessed.insert(node);
224 typename std::map<CFGNodeType, Vertex>::iterator iter;
230 ROSE_ASSERT(src.getNode());
232 boost::tie(iter, inserted) = nodesAdded.insert(std::make_pair(src,
Vertex()));
236 from = add_vertex(*
this);
245 std::vector<CFGEdgeType>
outEdges = node.outEdges();
247 BOOST_FOREACH(
const CFGEdgeType& cfgEdge, outEdges)
251 ROSE_ASSERT(tar.getNode());
253 boost::tie(iter, inserted) = nodesAdded.insert(std::make_pair(tar,
Vertex()));
257 to = add_vertex(*
this);
267 Edge edge = add_edge(from, to, *
this).first;
271 buildCFG(tar, nodesAdded, nodesProcessed);
275 template <
class CFGNodeT,
class CFGEdgeT>
278 if (!dominatorTree_.empty())
279 return dominatorTree_;
281 boost::associative_property_map<VertexVertexMap> domTreePredMap(dominatorTree_);
284 boost::lengauer_tarjan_dominator_tree(*
this, entry_, domTreePredMap);
285 return dominatorTree_;
288 template <
class CFGNodeT,
class CFGEdgeT>
291 if (!postdominatorTree_.empty())
292 return postdominatorTree_;
294 boost::associative_property_map<VertexVertexMap> postdomTreePredMap(postdominatorTree_);
297 boost::lengauer_tarjan_dominator_tree(boost::make_reverse_graph(*
this), exit_, postdomTreePredMap);
298 return postdominatorTree_;
301 template <
class CFGNodeT,
class CFGEdgeT>
306 boost::transpose_graph(*
this, reverseCFG,
311 reverseCFG.
entry_ = this->exit_;
312 reverseCFG.
exit_ = this->entry_;
316 template <
class CFGNodeT,
class CFGEdgeT>
320 std::vector<CFGNodePtr> allNodes;
321 BOOST_FOREACH (
Vertex v, boost::vertices(*
this))
322 allNodes.push_back((*
this)[v]);
326 template <
class CFGNodeT,
class CFGEdgeT>
330 std::vector<CFGEdgePtr> allEdges;
331 BOOST_FOREACH (
const Edge& e, boost::edges(*
this))
332 allEdges.push_back((*
this)[e]);
336 template <
class CFGNodeT,
class CFGEdgeT>
339 typename std::map<CFGNodeType, Vertex>::const_iterator vertexIter = nodesToVertices_.find(node);
340 if (vertexIter == nodesToVertices_.end())
341 return GraphTraits::null_vertex();
344 ROSE_ASSERT(*(*
this)[vertexIter->second] == node);
345 return vertexIter->second;
349 template <
class CFGNodeT,
class CFGEdgeT>
352 std::vector<Edge> backEdges;
357 BOOST_FOREACH (
const Edge& e, boost::edges(*
this))
359 Vertex src = boost::source(e, *
this);
360 Vertex tar = boost::target(e, *
this);
363 typename VertexVertexMap::const_iterator iter = dominatorTree_.find(src);
364 while (iter != dominatorTree_.end())
366 if (iter->second == tar)
368 backEdges.push_back(e);
371 iter = dominatorTree_.find(iter->second);
378 template <
class CFGNodeT,
class CFGEdgeT>
381 std::vector<Edge> backEdges = getAllBackEdges();
382 std::vector<Vertex> headers;
383 BOOST_FOREACH (
Edge e, backEdges)
384 headers.push_back(boost::target(e, *
this));