9#include <boost/graph/adjacency_list.hpp>
10#include <boost/bind/bind.hpp>
11#include <boost/tuple/tuple.hpp>
12#include <boost/graph/graphviz.hpp>
13#include <boost/graph/dominator_tree.hpp>
14#include <boost/graph/reverse_graph.hpp>
15#include <boost/graph/transpose_graph.hpp>
16#include <boost/algorithm/string.hpp>
22template <
class CFGNodeT,
class CFGEdgeT>
23class CFG :
public boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS,
24 boost::shared_ptr<CFGNodeT>, boost::shared_ptr<CFGEdgeT> >
27 typedef typename boost::graph_traits<CFG<CFGNodeT, CFGEdgeT> > GraphTraits;
30 typedef CFGNodeT CFGNodeType;
31 typedef CFGEdgeT CFGEdgeType;
33 typedef boost::shared_ptr<CFGNodeType> CFGNodePtr;
34 typedef boost::shared_ptr<CFGEdgeType> CFGEdgePtr;
36 typedef typename GraphTraits::vertex_descriptor
Vertex;
37 typedef typename GraphTraits::edge_descriptor
Edge;
39 typedef std::map<Vertex, Vertex> VertexVertexMap;
66 entry_(GraphTraits::null_vertex()),
67 exit_(GraphTraits::null_vertex())
74 entry_(GraphTraits::null_vertex()),
75 exit_(GraphTraits::null_vertex())
124 void buildCFG(
const CFGNodeType& node,
125 std::map<CFGNodeType, Vertex>& nodesAdded,
126 std::set<CFGNodeType>& nodesProcessed);
135 : cfg1(g1), cfg2(g2) {}
138 { cfg2[v2] = cfg1[v1]; }
148 : cfg1(g1), cfg2(g2) {}
150 void operator()(
const Edge& e1,
Edge& e2)
const
151 { cfg2[e2] = cfg1[e1]; }
162template <
class CFGNodeT,
class CFGEdgeT>
165 ROSE_ASSERT(funcDef);
169 nodesToVertices_.clear();
170 std::set<CFGNodeType> nodesProcessed;
174 entry_ = GraphTraits::null_vertex();
175 exit_ = GraphTraits::null_vertex();
177 buildCFG(CFGNodeType(funcDef->
cfgForBeginning()), nodesToVertices_, nodesProcessed);
182 ROSE_ASSERT(isSgFunctionDefinition((*
this)[entry_]->getNode()));
183 ROSE_ASSERT(isSgFunctionDefinition((*
this)[exit_]->getNode()));
186template <
class CFGNodeT,
class CFGEdgeT>
189 BOOST_FOREACH (
Vertex v, boost::vertices(*
this))
191 CFGNodePtr node = (*this)[v];
192 if (isSgFunctionDefinition(node->getNode()))
194 if (node->getIndex() == 0)
196 else if (node->getIndex() == 3)
203 if (exit_ == GraphTraits::null_vertex())
205 std::cerr <<
"This function may contain an infinite loop "
206 "inside so that its CFG cannot be built" << std::endl;
207 exit_ = add_vertex(*
this);
208 (*this)[exit_] = CFGNodePtr(
new CFGNodeType(funcDef_->cfgForEnd()));
211 ROSE_ASSERT(entry_ != GraphTraits::null_vertex());
212 ROSE_ASSERT(exit_ != GraphTraits::null_vertex());
215template <
class CFGNodeT,
class CFGEdgeT>
217 const CFGNodeType& node,
218 std::map<CFGNodeType, Vertex>& nodesAdded,
219 std::set<CFGNodeType>& nodesProcessed)
221 ROSE_ASSERT(node.getNode());
223 if (nodesProcessed.count(node) > 0)
225 nodesProcessed.insert(node);
227 typename std::map<CFGNodeType, Vertex>::iterator iter;
232 const CFGNodeType& src = node;
233 ROSE_ASSERT(src.getNode());
235 boost::tie(iter, inserted) = nodesAdded.insert(std::make_pair(src,
Vertex()));
239 from = add_vertex(*
this);
240 (*this)[from] = CFGNodePtr(
new CFGNodeType(src));
248 std::vector<CFGEdgeType> outEdges = node.outEdges();
250 BOOST_FOREACH(
const CFGEdgeType& cfgEdge, outEdges)
253 CFGNodeType tar = cfgEdge.target();
254 ROSE_ASSERT(tar.getNode());
256 boost::tie(iter, inserted) = nodesAdded.insert(std::make_pair(tar,
Vertex()));
260 to = add_vertex(*
this);
261 (*this)[to] = CFGNodePtr(
new CFGNodeType(tar));
270 Edge edge = add_edge(from, to, *
this).first;
271 (*this)[edge] = CFGEdgePtr(
new CFGEdgeType(cfgEdge));
274 buildCFG(tar, nodesAdded, nodesProcessed);
278template <
class CFGNodeT,
class CFGEdgeT>
281 if (!dominatorTree_.empty())
282 return dominatorTree_;
284 boost::associative_property_map<VertexVertexMap> domTreePredMap(dominatorTree_);
287 boost::lengauer_tarjan_dominator_tree(*
this, entry_, domTreePredMap);
288 return dominatorTree_;
291template <
class CFGNodeT,
class CFGEdgeT>
294 if (!postdominatorTree_.empty())
295 return postdominatorTree_;
297 boost::associative_property_map<VertexVertexMap> postdomTreePredMap(postdominatorTree_);
300 boost::lengauer_tarjan_dominator_tree(boost::make_reverse_graph(*
this), exit_, postdomTreePredMap);
301 return postdominatorTree_;
304template <
class CFGNodeT,
class CFGEdgeT>
309 boost::transpose_graph(*
this, reverseCFG,
314 reverseCFG.
entry_ = this->exit_;
315 reverseCFG.
exit_ = this->entry_;
319template <
class CFGNodeT,
class CFGEdgeT>
320std::vector<typename CFG<CFGNodeT, CFGEdgeT>::CFGNodePtr>
323 std::vector<CFGNodePtr> allNodes;
324 BOOST_FOREACH (
Vertex v, boost::vertices(*
this))
325 allNodes.push_back((*
this)[v]);
329template <
class CFGNodeT,
class CFGEdgeT>
330std::vector<typename CFG<CFGNodeT, CFGEdgeT>::CFGEdgePtr>
333 std::vector<CFGEdgePtr> allEdges;
334 BOOST_FOREACH (
const Edge& e, boost::edges(*
this))
335 allEdges.push_back((*
this)[e]);
339template <
class CFGNodeT,
class CFGEdgeT>
342 typename std::map<CFGNodeType, Vertex>::const_iterator vertexIter = nodesToVertices_.find(node);
343 if (vertexIter == nodesToVertices_.end())
344 return GraphTraits::null_vertex();
347 ROSE_ASSERT(*(*
this)[vertexIter->second] == node);
348 return vertexIter->second;
352template <
class CFGNodeT,
class CFGEdgeT>
355 std::vector<Edge> backEdges;
360 BOOST_FOREACH (
const Edge& e, boost::edges(*
this))
362 Vertex src = boost::source(e, *
this);
363 Vertex tar = boost::target(e, *
this);
366 typename VertexVertexMap::const_iterator iter = dominatorTree_.find(src);
367 while (iter != dominatorTree_.end())
369 if (iter->second == tar)
371 backEdges.push_back(e);
374 iter = dominatorTree_.find(iter->second);
381template <
class CFGNodeT,
class CFGEdgeT>
384 std::vector<Edge> backEdges = getAllBackEdges();
385 std::vector<Vertex> headers;
386 BOOST_FOREACH (
Edge e, backEdges)
387 headers.push_back(boost::target(e, *
this));
This class represents the concept of a scope in C++ (e.g. global scope, fuction scope,...
VirtualCFG::CFGNode cfgForBeginning()
Returns the CFG node for just before this AST node.
A class holding a Control Flow Graph.
void buildCFG(const CFGNodeType &node, std::map< CFGNodeType, Vertex > &nodesAdded, std::set< CFGNodeType > &nodesProcessed)
A internal funtion which builds the actual CFG (boost::graph).
SgFunctionDefinition * getFunctionDefinition() const
Get the function definition of this CFG.
VertexVertexMap postdominatorTree_
The postdominator tree of this CFG.
std::vector< CFGEdgePtr > getAllEdges() const
Get all CFG edges in this graph.
VertexVertexMap dominatorTree_
The dominator tree of this CFG.
void setEntryAndExit()
Find the entry and exit of this CFG and set the corresponding members.
std::vector< Vertex > getAllLoopHeaders()
Get all loop headers in this CFG. A natural loop only has one header.
std::map< CFGNodeType, Vertex > nodesToVertices_
A map from a CFG node to the corresponding vertex.
void build(SgFunctionDefinition *funcDef)
Build the actual CFG for the given function.
Vertex exit_
The exit node.
std::vector< CFGNodePtr > getAllNodes() const
Get all CFG nodes in this graph.
Vertex getVertexForNode(const CFGNodeType &node) const
Given a CFG node, returns the corresponding vertex in the graph.
std::vector< Edge > getAllBackEdges()
Get all back edges in the CFG. A back edge is one whose target dominates its source.
const Vertex & getExit() const
Get the exit node of the CFG.
const Vertex & getEntry() const
Get the entry node of the CFG.
CFG()
The default constructor.
const VertexVertexMap & getDominatorTree()
Build the dominator tree of this CFG.
Vertex entry_
The entry node.
CFG(SgFunctionDefinition *funcDef)
The constructor building the CFG.
CFG< CFGNodeT, CFGEdgeT > makeReverseCopy() const
Build a reverse CFG.
SgFunctionDefinition * funcDef_
The function definition of this CFG.
const VertexVertexMap & getPostdominatorTree()
Build the postdominator tree of this CFG.
This class is used to copy edges when calling copy_graph().
This class is used to copy vertices when calling copy_graph().