ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
iteratedDominanceFrontier.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <boostGraphCFG.h>
4 #include "rose.h"
5 #include <vector>
6 #include <set>
7 #include <map>
8 #include <iterator>
9 #include <boost/foreach.hpp>
10 #include <boost/graph/adjacency_list.hpp>
11 #include <boost/graph/topological_sort.hpp>
12 
13 namespace ssa_private
14 {
15  using namespace std;
16  using namespace boost;
17 
20  template<class CfgNodeT>
21  set<CfgNodeT> calculateIteratedDominanceFrontier(const map<CfgNodeT, set<CfgNodeT> >& dominanceFrontiers,
22  const vector<CfgNodeT>& startNodes)
23  {
24  set<CfgNodeT> result;
25  set<CfgNodeT> visitedNodes;
26  vector<CfgNodeT> worklist;
27 
28  worklist.insert(worklist.end(), startNodes.begin(), startNodes.end());
29 
30  while (!worklist.empty())
31  {
32  CfgNodeT currentNode = worklist.back();
33  worklist.pop_back();
34  visitedNodes.insert(currentNode);
35 
36  //Get the dominance frontier of the node and add it to the results
37  ROSE_ASSERT(dominanceFrontiers.count(currentNode) != 0);
38  const set<CfgNodeT>& dominanceFrontier = dominanceFrontiers.find(currentNode)->second;
39 
40  //Add all the children to the result and to the worklist
41 
42  BOOST_FOREACH(CfgNodeT dfNode, dominanceFrontier)
43  {
44  if (visitedNodes.count(dfNode) > 0)
45  continue;
46 
47  result.insert(dfNode);
48  worklist.push_back(dfNode);
49  }
50  }
51 
52  return result;
53  }
54 
58  template<class CfgNodeT, class CfgEdgeT>
59  map<CfgNodeT, set<CfgNodeT> > calculateDominanceFrontiers(SgFunctionDefinition* func, map<CfgNodeT, CfgNodeT>* iDominatorMap,
60  map<CfgNodeT, CfgNodeT>* iPostDominatorMap)
61  {
62  typedef CFG<CfgNodeT, CfgEdgeT> ControlFlowGraph;
63 
64  //Build a CFG first
65  ControlFlowGraph functionCfg(func);
66 
67  //Build the dominator tree
68  typename ControlFlowGraph::VertexVertexMap dominatorTreeMap = functionCfg.getDominatorTree();
69 
70  //TODO: This code converts a VertexVertex Map to a boost graph. Should be factored out
71  typedef adjacency_list<vecS, vecS, bidirectionalS, CfgNodeT> TreeType;
72  TreeType domTree;
73  typedef typename graph_traits<TreeType>::vertex_descriptor TreeVertex;
74 
75  set<CfgNodeT> addedNodes;
76  map<CfgNodeT, TreeVertex> cfgNodeToVertex;
77 
78  BOOST_FOREACH(typename ControlFlowGraph::VertexVertexMap::value_type& nodeDominatorPair, dominatorTreeMap)
79  {
80  CfgNodeT node = *functionCfg[nodeDominatorPair.first];
81  CfgNodeT dominator = *functionCfg[nodeDominatorPair.second];
82 
83  if (addedNodes.count(dominator) == 0)
84  {
85  TreeVertex newVertex = add_vertex(domTree);
86  cfgNodeToVertex[dominator] = newVertex;
87  domTree[newVertex] = dominator;
88  addedNodes.insert(dominator);
89  }
90 
91  if (addedNodes.count(node) == 0)
92  {
93  TreeVertex newVertex = add_vertex(domTree);
94  cfgNodeToVertex[node] = newVertex;
95  domTree[newVertex] = node;
96  addedNodes.insert(node);
97  }
98 
99  //Add the edge from dominator to node
100  add_edge(cfgNodeToVertex[dominator], cfgNodeToVertex[node], domTree);
101 
102  if (iDominatorMap != NULL)
103  {
104  ROSE_ASSERT(iDominatorMap->count(node) == 0);
105  iDominatorMap->insert(make_pair(node, dominator));
106  }
107  }
108 
109  //Get a topological ordering of the vertices
110  vector<TreeVertex> reverseTopological;
111  topological_sort(domTree, back_inserter(reverseTopological));
112 
113  //Calculate all the dominance frontiers. This algorithm is from figure 10, Cytron et. al 1991
114  map<CfgNodeT, set<CfgNodeT> > dominanceFrontiers;
115 
116  BOOST_FOREACH(TreeVertex v, reverseTopological)
117  {
118  CfgNodeT currentNode = domTree[v];
119  set<CfgNodeT>& currentDominanceFrontier = dominanceFrontiers[currentNode];
120 
121  //Local contribution: Iterate over all the successors of v in the control flow graph
122 
123  BOOST_FOREACH(CfgEdgeT outEdge, currentNode.outEdges())
124  {
125  CfgNodeT successor = outEdge.target();
126 
127  //Get the immediate dominator of the successor
128  typename ControlFlowGraph::Vertex successorVertex = functionCfg.getVertexForNode(successor);
129 #if !USE_ROSE
130  // DQ (11/3/2011): EDG compilains about this (but GNU allowed it, I think that EDG might be correct.
131  // since it might be a private variable. But since we are only trying to compile ROSE with ROSE (using the
132  // new EDG 4.3 front-end as a tests) we can just skip this case for now.
133  ROSE_ASSERT(successorVertex != ControlFlowGraph::GraphTraits::null_vertex());
134 #endif
135  ROSE_ASSERT(dominatorTreeMap.count(successorVertex) == 1);
136  typename ControlFlowGraph::Vertex iDominatorVertex = dominatorTreeMap[successorVertex];
137  CfgNodeT iDominator = *functionCfg[iDominatorVertex];
138 
139  //If we have a successor that we don't dominate, that successor is in our dominance frontier
140  if (iDominator != currentNode)
141  {
142  currentDominanceFrontier.insert(successor);
143  }
144  }
145 
146  //"Up" contribution. Iterate over all children in the dominator tree
147  typename graph_traits<TreeType>::adjacency_iterator currentIter, lastIter;
148  for (tie(currentIter, lastIter) = adjacent_vertices(v, domTree); currentIter != lastIter; currentIter++)
149  {
150  CfgNodeT childNode = domTree[*currentIter];
151  const set<CfgNodeT>& childDominanceFrontier = dominanceFrontiers[childNode];
152 
153  BOOST_FOREACH(CfgNodeT childDFNode, childDominanceFrontier)
154  {
155  //Get the immediate dominator of the child DF node
156  typename ControlFlowGraph::Vertex childDFVertex = functionCfg.getVertexForNode(childDFNode);
157 #if !USE_ROSE
158  // DQ (11/3/2011): EDG compilains about this (but GNU allowed it, I think that EDG might be correct.
159  // since it might be a private variable. But since we are only trying to compile ROSE with ROSE (using the
160  // new EDG 4.3 front-end as a tests) we can just skip this case for now.
161  ROSE_ASSERT(childDFVertex != ControlFlowGraph::GraphTraits::null_vertex());
162 #endif
163  ROSE_ASSERT(dominatorTreeMap.count(childDFVertex) == 1);
164  typename ControlFlowGraph::Vertex iDominatorVertex = dominatorTreeMap[childDFVertex];
165  CfgNodeT iDominator = *functionCfg[iDominatorVertex];
166 
167  if (iDominator != currentNode)
168  {
169  currentDominanceFrontier.insert(childDFNode);
170  }
171  }
172  }
173  }
174 
175  //While we're at it, calculate the postdominator tree
176  if (iPostDominatorMap != NULL)
177  {
178  typename ControlFlowGraph::VertexVertexMap postDominatorTreeMap = functionCfg.getPostdominatorTree();
179 
180  BOOST_FOREACH(typename ControlFlowGraph::VertexVertexMap::value_type& nodePostDominatorPair, postDominatorTreeMap)
181  {
182  CfgNodeT node = *functionCfg[nodePostDominatorPair.first];
183  CfgNodeT postDominator = *functionCfg[nodePostDominatorPair.second];
184 
185  ROSE_ASSERT(iPostDominatorMap->count(node) == 0);
186  iPostDominatorMap->insert(make_pair(node, postDominator));
187  }
188  }
189 
190  return dominanceFrontiers;
191  }
192 
193 }