Skip to content

Commit b66a6cc

Browse files
committed
Use vector-of-structs of preds/semi for Lengauer-Tarjan
Closes boostorg#383
1 parent ce1daeb commit b66a6cc

File tree

1 file changed

+54
-21
lines changed

1 file changed

+54
-21
lines changed

include/boost/graph/dominator_tree.hpp

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,33 @@ namespace detail
6262
Tag >(timeMap, v, t);
6363
}
6464

65+
// Auxiliary structure of different kinds of predecessors are used to
66+
// calculate the semidominators: ancestor, semidominator, and the ancestor
67+
// with the lowest semidominator (`best`). Placing these predecessors in a
68+
// structure let us organize a "vector of structs" what improves cache
69+
// efficiency.
70+
template < class Graph > struct preds
71+
{
72+
preds()
73+
: semi(graph_traits< Graph >::null_vertex())
74+
, ancestor(graph_traits< Graph >::null_vertex())
75+
, best(graph_traits< Graph >::null_vertex())
76+
{
77+
}
78+
79+
typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
80+
81+
void set_ancestor(const preds& pr) { ancestor = pr.ancestor; }
82+
83+
void set_ancestor(const Vertex& v) { ancestor = v; }
84+
85+
void set_best(const Vertex& v) { best = v; }
86+
87+
void set_semi(const Vertex& v) { semi = v; }
88+
89+
Vertex semi, ancestor, best;
90+
};
91+
6592
template < class Graph, class IndexMap, class TimeMap, class PredMap,
6693
class DomTreePredMap >
6794
class dominator_visitor
@@ -80,13 +107,9 @@ namespace detail
80107
*/
81108
dominator_visitor(const Graph& g, const Vertex& entry,
82109
const IndexMap& indexMap, DomTreePredMap domTreePredMap)
83-
: semi_(num_vertices(g))
84-
, ancestor_(num_vertices(g), graph_traits< Graph >::null_vertex())
85-
, samedom_(ancestor_)
86-
, best_(semi_)
87-
, semiMap_(make_iterator_property_map(semi_.begin(), indexMap))
88-
, ancestorMap_(make_iterator_property_map(ancestor_.begin(), indexMap))
89-
, bestMap_(make_iterator_property_map(best_.begin(), indexMap))
110+
: preds_(num_vertices(g))
111+
, predsMap_(make_iterator_property_map(preds_.begin(), indexMap))
112+
, samedom_(num_vertices(g), graph_traits< Graph >::null_vertex())
90113
, buckets_(num_vertices(g))
91114
, bucketMap_(make_iterator_property_map(buckets_.begin(), indexMap))
92115
, entry_(entry)
@@ -132,18 +155,20 @@ namespace detail
132155
if (get(dfnumMap, v) <= get(dfnumMap, n))
133156
s2 = v;
134157
else
135-
s2 = get(semiMap_, ancestor_with_lowest_semi_(v, dfnumMap));
158+
s2 = get(predsMap_, ancestor_with_lowest_semi_(v, dfnumMap))
159+
.semi;
136160

137161
if (get(dfnumMap, s2) < get(dfnumMap, s))
138162
s = s2;
139163
}
140-
put(semiMap_, n, s);
164+
preds< Graph >& preds_of_n = get(predsMap_, n);
165+
preds_of_n.set_semi(s);
141166

142167
// 2. Calculation of n's dominator is deferred until
143168
// the path from s to n has been linked into the forest
144169
get(bucketMap_, s).push_back(n);
145-
get(ancestorMap_, n) = p;
146-
get(bestMap_, n) = n;
170+
preds_of_n.set_ancestor(p);
171+
preds_of_n.set_best(n);
147172

148173
// 3. Now that the path from p to v has been linked into
149174
// the spanning forest, these lines calculate the dominator of v,
@@ -161,7 +186,7 @@ namespace detail
161186
{
162187
const Vertex v(*buckItr);
163188
const Vertex y(ancestor_with_lowest_semi_(v, dfnumMap));
164-
if (get(semiMap_, y) == get(semiMap_, v))
189+
if (get(predsMap_, y).semi == get(predsMap_, v).semi)
165190
put(domTreePredMap_, v, p);
166191
else
167192
put(samedomMap, v, y);
@@ -177,24 +202,32 @@ namespace detail
177202
const Vertex ancestor_with_lowest_semi_(
178203
const Vertex& v, const TimeMap& dfnumMap)
179204
{
180-
const Vertex a(get(ancestorMap_, v));
205+
const Vertex a(get(predsMap_, v).ancestor);
206+
const preds< Graph >& preds_of_a = get(predsMap_, a);
207+
208+
preds< Graph >& preds_of_v = get(predsMap_, v);
181209

182-
if (get(ancestorMap_, a) != graph_traits< Graph >::null_vertex())
210+
if (preds_of_a.ancestor != graph_traits< Graph >::null_vertex())
183211
{
184212
const Vertex b(ancestor_with_lowest_semi_(a, dfnumMap));
213+
const preds< Graph >& preds_of_b = get(predsMap_, b);
185214

186-
put(ancestorMap_, v, get(ancestorMap_, a));
215+
preds_of_v.set_ancestor(preds_of_a);
187216

188-
if (get(dfnumMap, get(semiMap_, b))
189-
< get(dfnumMap, get(semiMap_, get(bestMap_, v))))
190-
put(bestMap_, v, b);
217+
if (get(dfnumMap, preds_of_b.semi)
218+
< get(dfnumMap, get(predsMap_, preds_of_v.best).semi))
219+
preds_of_v.set_best(b);
191220
}
192221

193-
return get(bestMap_, v);
222+
return preds_of_v.best;
194223
}
195224

196-
std::vector< Vertex > semi_, ancestor_, samedom_, best_;
197-
PredMap semiMap_, ancestorMap_, bestMap_;
225+
std::vector< preds< Graph > > preds_;
226+
iterator_property_map< typename std::vector< preds< Graph > >::iterator,
227+
IndexMap >
228+
predsMap_;
229+
230+
std::vector< Vertex > samedom_;
198231
std::vector< std::vector< Vertex > > buckets_;
199232

200233
iterator_property_map<

0 commit comments

Comments
 (0)