Jlm
cfg-node.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2013 2014 2015 Nico Reißmann <nico.reissmann@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #ifndef JLM_LLVM_IR_CFG_NODE_HPP
7 #define JLM_LLVM_IR_CFG_NODE_HPP
8 
9 #include <jlm/util/common.hpp>
12 
13 #include <memory>
14 #include <unordered_set>
15 #include <vector>
16 
17 namespace jlm::llvm
18 {
19 
20 class BasicBlock;
21 class ControlFlowGraph;
22 class ControlFlowGraphNode;
23 
25 {
26 public:
27  ~ControlFlowGraphEdge() noexcept = default;
28 
32  size_t index) noexcept;
33 
34  ControlFlowGraphEdge(const ControlFlowGraphEdge & other) = delete;
35 
37 
39  operator=(const ControlFlowGraphEdge & other) = delete;
40 
42  operator=(ControlFlowGraphEdge && other) = default;
43 
44  void
45  divert(ControlFlowGraphNode * new_sink);
46 
47  BasicBlock *
48  split();
49 
50  [[nodiscard]] ControlFlowGraphNode *
51  source() const noexcept
52  {
53  return source_;
54  }
55 
56  [[nodiscard]] ControlFlowGraphNode *
57  sink() const noexcept
58  {
59  return sink_;
60  }
61 
65  size_t
66  index() const noexcept
67  {
68  return index_;
69  }
70 
71  bool
72  is_selfloop() const noexcept
73  {
74  return source_ == sink_;
75  }
76 
77 private:
80  size_t index_;
81 
83 };
84 
86 {
87  using inedge_iterator = util::
88  PtrIterator<ControlFlowGraphEdge, std::unordered_set<ControlFlowGraphEdge *>::const_iterator>;
90 
93  std::vector<std::unique_ptr<ControlFlowGraphEdge>>::const_iterator>;
95 
96 public:
97  virtual ~ControlFlowGraphNode() noexcept;
98 
99 protected:
101  : cfg_(cfg)
102  {}
103 
104 public:
106  cfg() const noexcept
107  {
108  return cfg_;
109  }
110 
111  size_t
112  NumOutEdges() const noexcept;
113 
114  [[nodiscard]] ControlFlowGraphEdge *
115  OutEdge(size_t n) const
116  {
117  JLM_ASSERT(n < NumOutEdges());
118  return outedges_[n].get();
119  }
120 
122  OutEdges() const
123  {
124  return outedge_iterator_range(
125  outedge_iterator(outedges_.begin()),
126  outedge_iterator(outedges_.end()));
127  }
128 
131  {
132  outedges_.push_back(std::make_unique<ControlFlowGraphEdge>(this, sink, NumOutEdges()));
133  sink->inedges_.insert(outedges_.back().get());
134  return outedges_.back().get();
135  }
136 
137  void
138  remove_outedge(size_t n)
139  {
140  JLM_ASSERT(n < NumOutEdges());
141  auto edge = outedges_[n].get();
142 
143  edge->sink()->inedges_.erase(edge);
144  for (size_t i = n + 1; i < NumOutEdges(); i++)
145  {
146  outedges_[i - 1] = std::move(outedges_[i]);
147  outedges_[i - 1]->index_ = outedges_[i - 1]->index_ - 1;
148  }
149  outedges_.resize(NumOutEdges() - 1);
150  }
151 
152  void
154  {
155  while (NumOutEdges() != 0)
157  }
158 
159  size_t
160  NumInEdges() const noexcept;
161 
163  InEdges() const
164  {
165  return inedge_iterator_range(
166  inedge_iterator(inedges_.begin()),
167  inedge_iterator(inedges_.end()));
168  }
169 
170  inline void
172  {
173  if (this == new_successor)
174  return;
175 
176  while (NumInEdges())
177  InEdges().begin()->divert(new_successor);
178  }
179 
180  void
181  remove_inedges();
182 
183  bool
184  no_predecessor() const noexcept;
185 
186  bool
187  single_predecessor() const noexcept;
188 
189  bool
190  no_successor() const noexcept;
191 
192  bool
193  single_successor() const noexcept;
194 
195  bool
196  is_branch() const noexcept
197  {
198  return NumOutEdges() > 1;
199  }
200 
201  bool
202  has_selfloop_edge() const noexcept;
203 
204 private:
206  std::vector<std::unique_ptr<ControlFlowGraphEdge>> outedges_;
207  std::unordered_set<ControlFlowGraphEdge *> inedges_;
208 
210 };
211 
212 template<class T>
213 static inline bool
214 is(const ControlFlowGraphNode * node) noexcept
215 {
216  static_assert(
217  std::is_base_of<ControlFlowGraphNode, T>::value,
218  "Template parameter T must be derived from jlm::ControlFlowGraphNode.");
219 
220  return dynamic_cast<const T *>(node) != nullptr;
221 }
222 
223 }
224 
225 #endif
size_t index() const noexcept
Definition: cfg-node.hpp:66
ControlFlowGraphNode * sink_
Definition: cfg-node.hpp:79
~ControlFlowGraphEdge() noexcept=default
ControlFlowGraphNode * sink() const noexcept
Definition: cfg-node.hpp:57
bool is_selfloop() const noexcept
Definition: cfg-node.hpp:72
ControlFlowGraphNode * source_
Definition: cfg-node.hpp:78
void divert(ControlFlowGraphNode *new_sink)
Definition: cfg-node.cpp:23
ControlFlowGraphNode * source() const noexcept
Definition: cfg-node.hpp:51
bool single_successor() const noexcept
Definition: cfg-node.cpp:97
util::IteratorRange< inedge_iterator > inedge_iterator_range
Definition: cfg-node.hpp:89
bool is_branch() const noexcept
Definition: cfg-node.hpp:196
std::vector< std::unique_ptr< ControlFlowGraphEdge > > outedges_
Definition: cfg-node.hpp:206
ControlFlowGraphEdge * add_outedge(ControlFlowGraphNode *sink)
Definition: cfg-node.hpp:130
inedge_iterator_range InEdges() const
Definition: cfg-node.hpp:163
bool single_predecessor() const noexcept
Definition: cfg-node.cpp:75
ControlFlowGraphEdge * OutEdge(size_t n) const
Definition: cfg-node.hpp:115
std::unordered_set< ControlFlowGraphEdge * > inedges_
Definition: cfg-node.hpp:207
bool has_selfloop_edge() const noexcept
Definition: cfg-node.cpp:113
size_t NumInEdges() const noexcept
Definition: cfg-node.cpp:63
util::PtrIterator< ControlFlowGraphEdge, std::vector< std::unique_ptr< ControlFlowGraphEdge > >::const_iterator > outedge_iterator
Definition: cfg-node.hpp:93
virtual ~ControlFlowGraphNode() noexcept
bool no_predecessor() const noexcept
Definition: cfg-node.cpp:69
util::PtrIterator< ControlFlowGraphEdge, std::unordered_set< ControlFlowGraphEdge * >::const_iterator > inedge_iterator
Definition: cfg-node.hpp:88
ControlFlowGraph & cfg() const noexcept
Definition: cfg-node.hpp:106
outedge_iterator_range OutEdges() const
Definition: cfg-node.hpp:122
bool no_successor() const noexcept
Definition: cfg-node.cpp:91
size_t NumOutEdges() const noexcept
Definition: cfg-node.cpp:46
void divert_inedges(llvm::ControlFlowGraphNode *new_successor)
Definition: cfg-node.hpp:171
util::IteratorRange< outedge_iterator > outedge_iterator_range
Definition: cfg-node.hpp:94
#define JLM_ASSERT(x)
Definition: common.hpp:16
Global memory state passed between functions.
static bool is(const AggregationNode *node)