annotate DEPENDENCIES/generic/include/boost/graph/dominator_tree.hpp @ 118:770eb830ec19 emscripten

Typo fix
author Chris Cannam
date Wed, 18 May 2016 16:14:08 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 //=======================================================================
Chris@16 2 // Copyright (C) 2005-2009 Jongsoo Park <jongsoo.park -at- gmail.com>
Chris@16 3 //
Chris@16 4 // Distributed under the Boost Software License, Version 1.0.
Chris@16 5 // (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 6 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 7 //=======================================================================
Chris@16 8
Chris@16 9 #ifndef BOOST_GRAPH_DOMINATOR_HPP
Chris@16 10 #define BOOST_GRAPH_DOMINATOR_HPP
Chris@16 11
Chris@16 12 #include <boost/config.hpp>
Chris@16 13 #include <deque>
Chris@16 14 #include <set>
Chris@16 15 #include <boost/graph/depth_first_search.hpp>
Chris@16 16 #include <boost/concept/assert.hpp>
Chris@16 17
Chris@16 18 // Dominator tree computation
Chris@16 19
Chris@16 20 namespace boost {
Chris@16 21 namespace detail {
Chris@16 22 /**
Chris@16 23 * An extended time_stamper which also records vertices for each dfs number
Chris@16 24 */
Chris@16 25 template<class TimeMap, class VertexVector, class TimeT, class Tag>
Chris@16 26 class time_stamper_with_vertex_vector
Chris@16 27 : public base_visitor<
Chris@16 28 time_stamper_with_vertex_vector<TimeMap, VertexVector, TimeT, Tag> >
Chris@16 29 {
Chris@16 30 public :
Chris@16 31 typedef Tag event_filter;
Chris@16 32 time_stamper_with_vertex_vector(TimeMap timeMap, VertexVector& v,
Chris@16 33 TimeT& t)
Chris@16 34 : timeStamper_(timeMap, t), v_(v) { }
Chris@16 35
Chris@16 36 template<class Graph>
Chris@16 37 void
Chris@16 38 operator()(const typename property_traits<TimeMap>::key_type& v,
Chris@16 39 const Graph& g)
Chris@16 40 {
Chris@16 41 timeStamper_(v, g);
Chris@16 42 v_[timeStamper_.m_time] = v;
Chris@16 43 }
Chris@16 44
Chris@16 45 private :
Chris@16 46 time_stamper<TimeMap, TimeT, Tag> timeStamper_;
Chris@16 47 VertexVector& v_;
Chris@16 48 };
Chris@16 49
Chris@16 50 /**
Chris@16 51 * A convenient way to create a time_stamper_with_vertex_vector
Chris@16 52 */
Chris@16 53 template<class TimeMap, class VertexVector, class TimeT, class Tag>
Chris@16 54 time_stamper_with_vertex_vector<TimeMap, VertexVector, TimeT, Tag>
Chris@16 55 stamp_times_with_vertex_vector(TimeMap timeMap, VertexVector& v, TimeT& t,
Chris@16 56 Tag)
Chris@16 57 {
Chris@16 58 return time_stamper_with_vertex_vector<TimeMap, VertexVector, TimeT,
Chris@16 59 Tag>(timeMap, v, t);
Chris@16 60 }
Chris@16 61
Chris@16 62 template<class Graph, class IndexMap, class TimeMap, class PredMap,
Chris@16 63 class DomTreePredMap>
Chris@16 64 class dominator_visitor
Chris@16 65 {
Chris@16 66 typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
Chris@16 67 typedef typename graph_traits<Graph>::vertices_size_type VerticesSizeType;
Chris@16 68
Chris@16 69 public :
Chris@16 70 /**
Chris@16 71 * @param g [in] the target graph of the dominator tree
Chris@16 72 * @param entry [in] the entry node of g
Chris@16 73 * @param domTreePredMap [out] the immediate dominator map
Chris@16 74 * (parent map in dominator tree)
Chris@16 75 */
Chris@16 76 dominator_visitor(const Graph& g, const Vertex& entry,
Chris@16 77 DomTreePredMap domTreePredMap)
Chris@16 78 : semi_(num_vertices(g)),
Chris@16 79 ancestor_(num_vertices(g), graph_traits<Graph>::null_vertex()),
Chris@16 80 samedom_(ancestor_),
Chris@16 81 best_(semi_),
Chris@16 82 semiMap_(make_iterator_property_map(semi_.begin(),
Chris@16 83 get(vertex_index, g))),
Chris@16 84 ancestorMap_(make_iterator_property_map(ancestor_.begin(),
Chris@16 85 get(vertex_index, g))),
Chris@16 86 bestMap_(make_iterator_property_map(best_.begin(),
Chris@16 87 get(vertex_index, g))),
Chris@16 88 buckets_(num_vertices(g)),
Chris@16 89 bucketMap_(make_iterator_property_map(buckets_.begin(),
Chris@16 90 get(vertex_index, g))),
Chris@16 91 entry_(entry),
Chris@16 92 domTreePredMap_(domTreePredMap),
Chris@16 93 numOfVertices_(num_vertices(g)),
Chris@16 94 samedomMap(make_iterator_property_map(samedom_.begin(),
Chris@16 95 get(vertex_index, g)))
Chris@16 96 {
Chris@16 97 }
Chris@16 98
Chris@16 99 void
Chris@16 100 operator()(const Vertex& n, const TimeMap& dfnumMap,
Chris@16 101 const PredMap& parentMap, const Graph& g)
Chris@16 102 {
Chris@16 103 if (n == entry_) return;
Chris@16 104
Chris@16 105 const Vertex p(get(parentMap, n));
Chris@16 106 Vertex s(p);
Chris@16 107
Chris@16 108 // 1. Calculate the semidominator of n,
Chris@16 109 // based on the semidominator thm.
Chris@16 110 // * Semidominator thm. : To find the semidominator of a node n,
Chris@16 111 // consider all predecessors v of n in the CFG (Control Flow Graph).
Chris@16 112 // - If v is a proper ancestor of n in the spanning tree
Chris@16 113 // (so dfnum(v) < dfnum(n)), then v is a candidate for semi(n)
Chris@16 114 // - If v is a non-ancestor of n (so dfnum(v) > dfnum(n))
Chris@16 115 // then for each u that is an ancestor of v (or u = v),
Chris@16 116 // Let semi(u) be a candidate for semi(n)
Chris@16 117 // of all these candidates, the one with lowest dfnum is
Chris@16 118 // the semidominator of n.
Chris@16 119
Chris@16 120 // For each predecessor of n
Chris@16 121 typename graph_traits<Graph>::in_edge_iterator inItr, inEnd;
Chris@16 122 for (boost::tie(inItr, inEnd) = in_edges(n, g); inItr != inEnd; ++inItr)
Chris@16 123 {
Chris@16 124 const Vertex v = source(*inItr, g);
Chris@16 125 // To deal with unreachable nodes
Chris@16 126 if (get(dfnumMap, v) < 0 || get(dfnumMap, v) >= numOfVertices_)
Chris@16 127 continue;
Chris@16 128
Chris@16 129 Vertex s2;
Chris@16 130 if (get(dfnumMap, v) <= get(dfnumMap, n))
Chris@16 131 s2 = v;
Chris@16 132 else
Chris@16 133 s2 = get(semiMap_, ancestor_with_lowest_semi_(v, dfnumMap));
Chris@16 134
Chris@16 135 if (get(dfnumMap, s2) < get(dfnumMap, s))
Chris@16 136 s = s2;
Chris@16 137 }
Chris@16 138 put(semiMap_, n, s);
Chris@16 139
Chris@16 140 // 2. Calculation of n's dominator is deferred until
Chris@16 141 // the path from s to n has been linked into the forest
Chris@16 142 get(bucketMap_, s).push_back(n);
Chris@16 143 get(ancestorMap_, n) = p;
Chris@16 144 get(bestMap_, n) = n;
Chris@16 145
Chris@16 146 // 3. Now that the path from p to v has been linked into
Chris@16 147 // the spanning forest, these lines calculate the dominator of v,
Chris@16 148 // based on the dominator thm., or else defer the calculation
Chris@16 149 // until y's dominator is known
Chris@16 150 // * Dominator thm. : On the spanning-tree path below semi(n) and
Chris@16 151 // above or including n, let y be the node
Chris@16 152 // with the smallest-numbered semidominator. Then,
Chris@16 153 //
Chris@16 154 // idom(n) = semi(n) if semi(y)=semi(n) or
Chris@16 155 // idom(y) if semi(y) != semi(n)
Chris@16 156 typename std::deque<Vertex>::iterator buckItr;
Chris@16 157 for (buckItr = get(bucketMap_, p).begin();
Chris@16 158 buckItr != get(bucketMap_, p).end();
Chris@16 159 ++buckItr)
Chris@16 160 {
Chris@16 161 const Vertex v(*buckItr);
Chris@16 162 const Vertex y(ancestor_with_lowest_semi_(v, dfnumMap));
Chris@16 163 if (get(semiMap_, y) == get(semiMap_, v))
Chris@16 164 put(domTreePredMap_, v, p);
Chris@16 165 else
Chris@16 166 put(samedomMap, v, y);
Chris@16 167 }
Chris@16 168
Chris@16 169 get(bucketMap_, p).clear();
Chris@16 170 }
Chris@16 171
Chris@16 172 protected :
Chris@16 173
Chris@16 174 /**
Chris@16 175 * Evaluate function in Tarjan's path compression
Chris@16 176 */
Chris@16 177 const Vertex
Chris@16 178 ancestor_with_lowest_semi_(const Vertex& v, const TimeMap& dfnumMap)
Chris@16 179 {
Chris@16 180 const Vertex a(get(ancestorMap_, v));
Chris@16 181
Chris@16 182 if (get(ancestorMap_, a) != graph_traits<Graph>::null_vertex())
Chris@16 183 {
Chris@16 184 const Vertex b(ancestor_with_lowest_semi_(a, dfnumMap));
Chris@16 185
Chris@16 186 put(ancestorMap_, v, get(ancestorMap_, a));
Chris@16 187
Chris@16 188 if (get(dfnumMap, get(semiMap_, b)) <
Chris@16 189 get(dfnumMap, get(semiMap_, get(bestMap_, v))))
Chris@16 190 put(bestMap_, v, b);
Chris@16 191 }
Chris@16 192
Chris@16 193 return get(bestMap_, v);
Chris@16 194 }
Chris@16 195
Chris@16 196 std::vector<Vertex> semi_, ancestor_, samedom_, best_;
Chris@16 197 PredMap semiMap_, ancestorMap_, bestMap_;
Chris@16 198 std::vector< std::deque<Vertex> > buckets_;
Chris@16 199
Chris@16 200 iterator_property_map<typename std::vector<std::deque<Vertex> >::iterator,
Chris@16 201 IndexMap> bucketMap_;
Chris@16 202
Chris@16 203 const Vertex& entry_;
Chris@16 204 DomTreePredMap domTreePredMap_;
Chris@16 205 const VerticesSizeType numOfVertices_;
Chris@16 206
Chris@16 207 public :
Chris@16 208
Chris@16 209 PredMap samedomMap;
Chris@16 210 };
Chris@16 211
Chris@16 212 } // namespace detail
Chris@16 213
Chris@16 214 /**
Chris@16 215 * @brief Build dominator tree using Lengauer-Tarjan algorithm.
Chris@16 216 * It takes O((V+E)log(V+E)) time.
Chris@16 217 *
Chris@16 218 * @pre dfnumMap, parentMap and verticesByDFNum have dfs results corresponding
Chris@16 219 * indexMap.
Chris@16 220 * If dfs has already run before,
Chris@16 221 * this function would be good for saving computations.
Chris@16 222 * @pre Unreachable nodes must be masked as
Chris@16 223 * graph_traits<Graph>::null_vertex in parentMap.
Chris@16 224 * @pre Unreachable nodes must be masked as
Chris@16 225 * (std::numeric_limits<VerticesSizeType>::max)() in dfnumMap.
Chris@16 226 *
Chris@16 227 * @param domTreePredMap [out] : immediate dominator map (parent map
Chris@16 228 * in dom. tree)
Chris@16 229 *
Chris@16 230 * @note reference Appel. p. 452~453. algorithm 19.9, 19.10.
Chris@16 231 *
Chris@16 232 * @todo : Optimization in Finding Dominators in Practice, Loukas Georgiadis
Chris@16 233 */
Chris@16 234 template<class Graph, class IndexMap, class TimeMap, class PredMap,
Chris@16 235 class VertexVector, class DomTreePredMap>
Chris@16 236 void
Chris@16 237 lengauer_tarjan_dominator_tree_without_dfs
Chris@16 238 (const Graph& g,
Chris@16 239 const typename graph_traits<Graph>::vertex_descriptor& entry,
Chris@16 240 const IndexMap& /*indexMap*/,
Chris@16 241 TimeMap dfnumMap, PredMap parentMap, VertexVector& verticesByDFNum,
Chris@16 242 DomTreePredMap domTreePredMap)
Chris@16 243 {
Chris@16 244 // Typedefs and concept check
Chris@16 245 typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
Chris@16 246 typedef typename graph_traits<Graph>::vertices_size_type VerticesSizeType;
Chris@16 247
Chris@16 248 BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept<Graph> ));
Chris@16 249
Chris@16 250 const VerticesSizeType numOfVertices = num_vertices(g);
Chris@16 251 if (numOfVertices == 0) return;
Chris@16 252
Chris@16 253 // 1. Visit each vertex in reverse post order and calculate sdom.
Chris@16 254 detail::dominator_visitor<Graph, IndexMap, TimeMap, PredMap, DomTreePredMap>
Chris@16 255 visitor(g, entry, domTreePredMap);
Chris@16 256
Chris@16 257 VerticesSizeType i;
Chris@16 258 for (i = 0; i < numOfVertices; ++i)
Chris@16 259 {
Chris@16 260 const Vertex u(verticesByDFNum[numOfVertices - 1 - i]);
Chris@16 261 if (u != graph_traits<Graph>::null_vertex())
Chris@16 262 visitor(u, dfnumMap, parentMap, g);
Chris@16 263 }
Chris@16 264
Chris@16 265 // 2. Now all the deferred dominator calculations,
Chris@16 266 // based on the second clause of the dominator thm., are performed
Chris@16 267 for (i = 0; i < numOfVertices; ++i)
Chris@16 268 {
Chris@16 269 const Vertex n(verticesByDFNum[i]);
Chris@16 270
Chris@16 271 if (n == entry || n == graph_traits<Graph>::null_vertex())
Chris@16 272 continue;
Chris@16 273
Chris@16 274 Vertex u = get(visitor.samedomMap, n);
Chris@16 275 if (u != graph_traits<Graph>::null_vertex())
Chris@16 276 {
Chris@16 277 put(domTreePredMap, n, get(domTreePredMap, u));
Chris@16 278 }
Chris@16 279 }
Chris@16 280 }
Chris@16 281
Chris@16 282 /**
Chris@16 283 * Unlike lengauer_tarjan_dominator_tree_without_dfs,
Chris@16 284 * dfs is run in this function and
Chris@16 285 * the result is written to dfnumMap, parentMap, vertices.
Chris@16 286 *
Chris@16 287 * If the result of dfs required after this algorithm,
Chris@16 288 * this function can eliminate the need of rerunning dfs.
Chris@16 289 */
Chris@16 290 template<class Graph, class IndexMap, class TimeMap, class PredMap,
Chris@16 291 class VertexVector, class DomTreePredMap>
Chris@16 292 void
Chris@16 293 lengauer_tarjan_dominator_tree
Chris@16 294 (const Graph& g,
Chris@16 295 const typename graph_traits<Graph>::vertex_descriptor& entry,
Chris@16 296 const IndexMap& indexMap,
Chris@16 297 TimeMap dfnumMap, PredMap parentMap, VertexVector& verticesByDFNum,
Chris@16 298 DomTreePredMap domTreePredMap)
Chris@16 299 {
Chris@16 300 // Typedefs and concept check
Chris@16 301 typedef typename graph_traits<Graph>::vertices_size_type VerticesSizeType;
Chris@16 302
Chris@16 303 BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept<Graph> ));
Chris@16 304
Chris@16 305 // 1. Depth first visit
Chris@16 306 const VerticesSizeType numOfVertices = num_vertices(g);
Chris@16 307 if (numOfVertices == 0) return;
Chris@16 308
Chris@16 309 VerticesSizeType time =
Chris@16 310 (std::numeric_limits<VerticesSizeType>::max)();
Chris@16 311 std::vector<default_color_type>
Chris@16 312 colors(numOfVertices, color_traits<default_color_type>::white());
Chris@16 313 depth_first_visit
Chris@16 314 (g, entry,
Chris@16 315 make_dfs_visitor
Chris@16 316 (make_pair(record_predecessors(parentMap, on_tree_edge()),
Chris@16 317 detail::stamp_times_with_vertex_vector
Chris@16 318 (dfnumMap, verticesByDFNum, time, on_discover_vertex()))),
Chris@16 319 make_iterator_property_map(colors.begin(), indexMap));
Chris@16 320
Chris@16 321 // 2. Run main algorithm.
Chris@16 322 lengauer_tarjan_dominator_tree_without_dfs(g, entry, indexMap, dfnumMap,
Chris@16 323 parentMap, verticesByDFNum,
Chris@16 324 domTreePredMap);
Chris@16 325 }
Chris@16 326
Chris@16 327 /**
Chris@16 328 * Use vertex_index as IndexMap and make dfnumMap, parentMap, verticesByDFNum
Chris@16 329 * internally.
Chris@16 330 * If we don't need the result of dfs (dfnumMap, parentMap, verticesByDFNum),
Chris@16 331 * this function would be more convenient one.
Chris@16 332 */
Chris@16 333 template<class Graph, class DomTreePredMap>
Chris@16 334 void
Chris@16 335 lengauer_tarjan_dominator_tree
Chris@16 336 (const Graph& g,
Chris@16 337 const typename graph_traits<Graph>::vertex_descriptor& entry,
Chris@16 338 DomTreePredMap domTreePredMap)
Chris@16 339 {
Chris@16 340 // typedefs
Chris@16 341 typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
Chris@16 342 typedef typename graph_traits<Graph>::vertices_size_type VerticesSizeType;
Chris@16 343 typedef typename property_map<Graph, vertex_index_t>::const_type IndexMap;
Chris@16 344 typedef
Chris@16 345 iterator_property_map<typename std::vector<VerticesSizeType>::iterator,
Chris@16 346 IndexMap> TimeMap;
Chris@16 347 typedef
Chris@16 348 iterator_property_map<typename std::vector<Vertex>::iterator, IndexMap>
Chris@16 349 PredMap;
Chris@16 350
Chris@16 351 // Make property maps
Chris@16 352 const VerticesSizeType numOfVertices = num_vertices(g);
Chris@16 353 if (numOfVertices == 0) return;
Chris@16 354
Chris@16 355 const IndexMap indexMap = get(vertex_index, g);
Chris@16 356
Chris@16 357 std::vector<VerticesSizeType> dfnum(numOfVertices, 0);
Chris@16 358 TimeMap dfnumMap(make_iterator_property_map(dfnum.begin(), indexMap));
Chris@16 359
Chris@16 360 std::vector<Vertex> parent(numOfVertices,
Chris@16 361 graph_traits<Graph>::null_vertex());
Chris@16 362 PredMap parentMap(make_iterator_property_map(parent.begin(), indexMap));
Chris@16 363
Chris@16 364 std::vector<Vertex> verticesByDFNum(parent);
Chris@16 365
Chris@16 366 // Run main algorithm
Chris@16 367 lengauer_tarjan_dominator_tree(g, entry,
Chris@16 368 indexMap, dfnumMap, parentMap,
Chris@16 369 verticesByDFNum, domTreePredMap);
Chris@16 370 }
Chris@16 371
Chris@16 372 /**
Chris@16 373 * Muchnick. p. 182, 184
Chris@16 374 *
Chris@16 375 * using iterative bit vector analysis
Chris@16 376 */
Chris@16 377 template<class Graph, class IndexMap, class DomTreePredMap>
Chris@16 378 void
Chris@16 379 iterative_bit_vector_dominator_tree
Chris@16 380 (const Graph& g,
Chris@16 381 const typename graph_traits<Graph>::vertex_descriptor& entry,
Chris@16 382 const IndexMap& indexMap,
Chris@16 383 DomTreePredMap domTreePredMap)
Chris@16 384 {
Chris@16 385 typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
Chris@16 386 typedef typename graph_traits<Graph>::vertex_iterator vertexItr;
Chris@16 387 typedef typename graph_traits<Graph>::vertices_size_type VerticesSizeType;
Chris@16 388 typedef
Chris@16 389 iterator_property_map<typename std::vector< std::set<Vertex> >::iterator,
Chris@16 390 IndexMap> vertexSetMap;
Chris@16 391
Chris@16 392 BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept<Graph> ));
Chris@16 393
Chris@16 394 // 1. Finding dominator
Chris@16 395 // 1.1. Initialize
Chris@16 396 const VerticesSizeType numOfVertices = num_vertices(g);
Chris@16 397 if (numOfVertices == 0) return;
Chris@16 398
Chris@16 399 vertexItr vi, viend;
Chris@16 400 boost::tie(vi, viend) = vertices(g);
Chris@16 401 const std::set<Vertex> N(vi, viend);
Chris@16 402
Chris@16 403 bool change = true;
Chris@16 404
Chris@16 405 std::vector< std::set<Vertex> > dom(numOfVertices, N);
Chris@16 406 vertexSetMap domMap(make_iterator_property_map(dom.begin(), indexMap));
Chris@16 407 get(domMap, entry).clear();
Chris@16 408 get(domMap, entry).insert(entry);
Chris@16 409
Chris@16 410 while (change)
Chris@16 411 {
Chris@16 412 change = false;
Chris@16 413 for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
Chris@16 414 {
Chris@16 415 if (*vi == entry) continue;
Chris@16 416
Chris@16 417 std::set<Vertex> T(N);
Chris@16 418
Chris@16 419 typename graph_traits<Graph>::in_edge_iterator inItr, inEnd;
Chris@16 420 for (boost::tie(inItr, inEnd) = in_edges(*vi, g); inItr != inEnd; ++inItr)
Chris@16 421 {
Chris@16 422 const Vertex p = source(*inItr, g);
Chris@16 423
Chris@16 424 std::set<Vertex> tempSet;
Chris@16 425 std::set_intersection(T.begin(), T.end(),
Chris@16 426 get(domMap, p).begin(),
Chris@16 427 get(domMap, p).end(),
Chris@16 428 std::inserter(tempSet, tempSet.begin()));
Chris@16 429 T.swap(tempSet);
Chris@16 430 }
Chris@16 431
Chris@16 432 T.insert(*vi);
Chris@16 433 if (T != get(domMap, *vi))
Chris@16 434 {
Chris@16 435 change = true;
Chris@16 436 get(domMap, *vi).swap(T);
Chris@16 437 }
Chris@16 438 } // end of for (boost::tie(vi, viend) = vertices(g)
Chris@16 439 } // end of while(change)
Chris@16 440
Chris@16 441 // 2. Build dominator tree
Chris@16 442 for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
Chris@16 443 get(domMap, *vi).erase(*vi);
Chris@16 444
Chris@16 445 Graph domTree(numOfVertices);
Chris@16 446
Chris@16 447 for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
Chris@16 448 {
Chris@16 449 if (*vi == entry) continue;
Chris@16 450
Chris@16 451 // We have to iterate through copied dominator set
Chris@16 452 const std::set<Vertex> tempSet(get(domMap, *vi));
Chris@16 453 typename std::set<Vertex>::const_iterator s;
Chris@16 454 for (s = tempSet.begin(); s != tempSet.end(); ++s)
Chris@16 455 {
Chris@16 456 typename std::set<Vertex>::iterator t;
Chris@16 457 for (t = get(domMap, *vi).begin(); t != get(domMap, *vi).end(); )
Chris@16 458 {
Chris@16 459 typename std::set<Vertex>::iterator old_t = t;
Chris@16 460 ++t; // Done early because t may become invalid
Chris@16 461 if (*old_t == *s) continue;
Chris@16 462 if (get(domMap, *s).find(*old_t) != get(domMap, *s).end())
Chris@16 463 get(domMap, *vi).erase(old_t);
Chris@16 464 }
Chris@16 465 }
Chris@16 466 }
Chris@16 467
Chris@16 468 for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
Chris@16 469 {
Chris@16 470 if (*vi != entry && get(domMap, *vi).size() == 1)
Chris@16 471 {
Chris@16 472 Vertex temp = *get(domMap, *vi).begin();
Chris@16 473 put(domTreePredMap, *vi, temp);
Chris@16 474 }
Chris@16 475 }
Chris@16 476 }
Chris@16 477
Chris@16 478 template<class Graph, class DomTreePredMap>
Chris@16 479 void
Chris@16 480 iterative_bit_vector_dominator_tree
Chris@16 481 (const Graph& g,
Chris@16 482 const typename graph_traits<Graph>::vertex_descriptor& entry,
Chris@16 483 DomTreePredMap domTreePredMap)
Chris@16 484 {
Chris@16 485 typename property_map<Graph, vertex_index_t>::const_type
Chris@16 486 indexMap = get(vertex_index, g);
Chris@16 487
Chris@16 488 iterative_bit_vector_dominator_tree(g, entry, indexMap, domTreePredMap);
Chris@16 489 }
Chris@16 490 } // namespace boost
Chris@16 491
Chris@16 492 #endif // BOOST_GRAPH_DOMINATOR_HPP