1 #ifndef BACKSTROKE_CFG_H
2 #define BACKSTROKE_CFG_H
6 #include <boost/graph/adjacency_list.hpp>
7 #include <boost/bind.hpp>
8 #include <boost/foreach.hpp>
9 #include <boost/tuple/tuple.hpp>
10 #include <boost/graph/graphviz.hpp>
11 #include <boost/graph/dominator_tree.hpp>
12 #include <boost/graph/reverse_graph.hpp>
13 #include <boost/graph/transpose_graph.hpp>
14 #include <boost/algorithm/string.hpp>
20 #define foreach BOOST_FOREACH
24 template <
class CFGNodeType>
27 SgNode* node = cfgNode.getNode();
30 std::string nodeColor =
"black";
42 std::string funcName = funcDef->get_declaration()->get_name().str();
43 if (cfgNode.getIndex() == 0)
44 label =
"Entry\\n" + funcName;
45 else if (cfgNode.getIndex() == 3)
46 label =
"Exit\\n" + funcName;
52 boost::replace_all(content,
"\"",
"\\\"");
53 boost::replace_all(content,
"\\n",
"\\\\n");
62 out <<
"[label=\"" << label <<
"\", color=\"" << nodeColor <<
63 "\", style=\"" << (cfgNode.isInteresting()?
"solid" :
"dotted") <<
"\"]";
68 template <
class CFGEdgeType>
72 "\", style=\"" <<
"solid" <<
"\"]";
77 template <
class CFGNodeFilter>
class CFG;
114 template <
class CFGNodeFilter>
115 class CFG :
public boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS,
116 boost::shared_ptr<VirtualCFG::FilteredCFGNode<CFGNodeFilter> >,
117 boost::shared_ptr<VirtualCFG::FilteredCFGEdge<CFGNodeFilter> > >
119 typedef typename boost::graph_traits<CFG<CFGNodeFilter> >
GraphTraits;
128 typedef typename GraphTraits::vertex_descriptor
Vertex;
129 typedef typename GraphTraits::edge_descriptor
Edge;
202 void toDot(
const std::string& filename)
const;
228 std::map<CFGNodeType, Vertex>& nodesAdded,
229 std::set<CFGNodeType>& nodesProcessed);
277 template <
class CFGNodeFilter>
280 std::ofstream ofile(filename.c_str(), std::ios::out);
281 boost::write_graphviz(ofile, *
this,
286 template <
class CFGNodeFilter>
289 ROSE_ASSERT(funcDef);
293 nodesToVertices_.clear();
294 std::set<CFGNodeType> nodesProcessed;
298 entry_ = GraphTraits::null_vertex();
299 exit_ = GraphTraits::null_vertex();
310 template <
class CFGNodeFilter>
313 foreach (
Vertex v, boost::vertices(*
this))
318 if (node->getIndex() == 0)
320 else if (node->getIndex() == 3)
327 if (exit_ == GraphTraits::null_vertex())
329 std::cerr <<
"This function may contain an infinite loop "
330 "inside so that its CFG cannot be built" << std::endl;
331 exit_ = add_vertex(*
this);
335 ROSE_ASSERT(entry_ != GraphTraits::null_vertex());
336 ROSE_ASSERT(exit_ != GraphTraits::null_vertex());
339 template <
class CFGNodeFilter>
342 std::map<CFGNodeType, Vertex>& nodesAdded,
343 std::set<CFGNodeType>& nodesProcessed)
347 if (nodesProcessed.count(node) > 0)
349 nodesProcessed.insert(node);
351 typename std::map<CFGNodeType, Vertex>::iterator iter;
359 boost::tie(iter, inserted) = nodesAdded.insert(std::make_pair(src,
Vertex()));
363 from = add_vertex(*
this);
380 boost::tie(iter, inserted) = nodesAdded.insert(std::make_pair(tar,
Vertex()));
384 to = add_vertex(*
this);
394 Edge edge = add_edge(from, to, *
this).first;
398 buildCFG(tar, nodesAdded, nodesProcessed);
402 template <
class CFGNodeFilter>
405 if (!dominatorTree_.empty())
406 return dominatorTree_;
408 boost::associative_property_map<VertexVertexMap> domTreePredMap(dominatorTree_);
411 boost::lengauer_tarjan_dominator_tree(*
this, entry_, domTreePredMap);
412 return dominatorTree_;
415 template <
class CFGNodeFilter>
418 if (!postdominatorTree_.empty())
419 return postdominatorTree_;
421 boost::associative_property_map<VertexVertexMap> postdomTreePredMap(postdominatorTree_);
424 boost::lengauer_tarjan_dominator_tree(boost::make_reverse_graph(*
this), exit_, postdomTreePredMap);
425 return postdominatorTree_;
428 template <
class CFGNodeFilter>
433 boost::transpose_graph(*
this, reverseCFG,
438 reverseCFG.
entry_ = this->exit_;
439 reverseCFG.
exit_ = this->entry_;
444 template <
class CFGNodeFilter>
448 std::vector<CFGNodePtr> allNodes;
449 foreach (
Vertex v, boost::vertices(*
this))
450 allNodes.push_back((*
this)[v]);
466 template <
class CFGNodeFilter>
470 std::vector<CFGEdgePtr> allEdges;
471 foreach (
const Edge& e, boost::edges(*
this))
472 allEdges.push_back((*
this)[e]);
476 template <
class CFGNodeFilter>
479 typename std::map<CFGNodeType, Vertex>::const_iterator vertexIter = nodesToVertices_.find(node);
480 if (vertexIter == nodesToVertices_.end())
481 return GraphTraits::null_vertex();
484 ROSE_ASSERT(*(*
this)[vertexIter->second] == node);
485 return vertexIter->second;
489 template <
class CFGNodeFilter>
492 std::vector<Edge> backEdges;
497 foreach (
const Edge& e, boost::edges(*
this))
499 Vertex src = boost::source(e, *
this);
500 Vertex tar = boost::target(e, *
this);
503 typename VertexVertexMap::const_iterator iter = dominatorTree_.find(src);
504 while (iter != dominatorTree_.end())
506 if (iter->second == tar)
508 backEdges.push_back(e);
511 iter = dominatorTree_.find(iter->second);
518 template <
class CFGNodeFilter>
521 std::vector<Edge> backEdges = getAllBackEdges();
522 std::vector<Vertex> headers;
523 foreach (
Edge e, backEdges)
524 headers.push_back(boost::target(e, *
this));