Skip to content

Commit 45a0532

Browse files
author
Roland Leißa
committed
support for reverse edges
1 parent ad0f101 commit 45a0532

File tree

2 files changed

+42
-24
lines changed

2 files changed

+42
-24
lines changed

include/graphtool/graph.h

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,33 @@ class Graph {
2121

2222
public:
2323
Sym name() const { return name_; }
24-
size_t pre() const { return pre_; }
25-
size_t post() const { return post_; }
26-
size_t rp() const { return rp_; }
24+
template<size_t mode> size_t pre() const { return order_[mode].pre; }
25+
template<size_t mode> size_t post() const { return order_[mode].post; }
26+
template<size_t mode> size_t rp() const { return order_[mode].rp; }
2727

2828
void link(Node* succ) {
2929
this->succs_.emplace(succ);
3030
succ->preds_.emplace(this);
3131
}
32-
const auto& preds() const { return preds_; }
33-
const auto& succs() const { return succs_; }
32+
33+
template<size_t mode = 0> const auto& preds() const { return mode == 0 ? preds_ : succs_; }
34+
template<size_t mode = 0> const auto& succs() const { return mode == 0 ? succs_ : preds_; }
3435

3536
friend std::ostream& operator<<(std::ostream&, const Node&);
3637

3738
private:
38-
std::pair<size_t, size_t> number(size_t, size_t);
39+
template<size_t mode> std::pair<size_t, size_t> number(size_t, size_t);
3940

4041
Sym name_;
4142
NodeSet preds_, succs_;
42-
size_t pre_ = Not_Visited;
43-
size_t post_ = Not_Visited;
44-
size_t rp_ = Not_Visited;
43+
44+
struct Order {
45+
size_t pre = Not_Visited;
46+
size_t post = Not_Visited;
47+
size_t rp = Not_Visited;
48+
};
49+
50+
Order order_[2];
4551

4652
friend class Graph;
4753
};
@@ -65,13 +71,12 @@ class Graph {
6571
fe::Driver& driver() { return driver_; }
6672
Sym name() const { return name_; }
6773
const auto& nodes() const { return nodes_; }
68-
const auto& rpo() const { return rpo_; }
74+
template<size_t mode> const auto& rpo() const { return rpo_[mode]; }
6975
///@}
7076

7177
void set_name(Sym name) { name_ = name; }
7278
Node* node(Sym name);
7379
void critical_edge_elimination();
74-
7580
void number();
7681

7782
friend std::ostream& operator<<(std::ostream&, const Graph&);
@@ -88,12 +93,14 @@ class Graph {
8893
}
8994

9095
private:
96+
template<size_t mode> void number_();
97+
9198
fe::Driver& driver_;
9299
Sym name_;
93100
Node* entry_ = nullptr;
94101
Node* exit_ = nullptr;
95102
fe::SymMap<Node*> nodes_;
96-
std::vector<Node*> rpo_;
103+
std::vector<Node*> rpo_[2];
97104
};
98105

99106
} // namespace graphtool

src/graphtool/graph.cpp

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,32 @@ Graph::Node* Graph::node(Sym name) {
2121
*/
2222

2323
void Graph::number() {
24-
auto [n, m] = entry_->number(0, 0);
24+
number_<0>();
25+
number_<1>();
26+
}
27+
28+
template<size_t mode>
29+
void Graph::number_() {
30+
auto [n, m] = entry_->number<mode>(0, 0);
2531
assert(n == m);
26-
rpo_.resize(n);
32+
rpo_[mode].resize(n);
2733
for (auto [_, node] : nodes()) {
28-
if (node->post_ != Graph::Node::Not_Visited) {
29-
size_t i = n - node->post_ - 1;
30-
node->rp_ = i;
31-
rpo_[i] = node;
34+
auto& order = node->order_[mode];
35+
if (order.post != Graph::Node::Not_Visited) {
36+
size_t i = n - order.post - 1;
37+
order.rp = i;
38+
rpo_[mode][i] = node;
3239
}
3340
}
3441
}
3542

43+
template<size_t mode>
3644
std::pair<size_t, size_t> Graph::Node::number(size_t pre, size_t post) {
37-
if (pre_ == Not_Visited) {
38-
pre_ = pre++;
39-
for (auto succ : succs()) std::tie(pre, post) = succ->number(pre, post);
40-
post_ = post++;
45+
auto& order = order_[mode];
46+
if (order.pre == Not_Visited) {
47+
order.pre = pre++;
48+
for (auto succ : succs<mode>()) std::tie(pre, post) = succ->template number<mode>(pre, post);
49+
order.post = post++;
4150
}
4251
return {pre, post};
4352
}
@@ -70,12 +79,14 @@ void Graph::critical_edge_elimination() {
7079
*/
7180

7281
std::ostream& operator<<(std::ostream& os, const Graph::Node& node) {
73-
return os << std::format("\t\"{}|{}|{}|{}\"", node.name(), node.pre(), node.post(), node.rp());
82+
return os << std::format("\t\"{}[{}|{}|{}][{}|{}|{}]\"", node.name(),
83+
node.pre<0>(), node.post<0>(), node.rp<0>(),
84+
node.pre<1>(), node.post<1>(), node.rp<1>());
7485
}
7586

7687
std::ostream& operator<<(std::ostream& os, const Graph& graph) {
7788
os << std::format("digraph {} {{", graph.name()) << std::endl;
78-
for (const char* sep = ""; auto node : graph.rpo()) {
89+
for (const char* sep = ""; auto node : graph.rpo<0>()) {
7990
for (auto succ : node->succs())
8091
os << std::format("\t{} -> {}", *node, *succ) << sep;
8192
sep = "\n";

0 commit comments

Comments
 (0)