Jlm
cfg.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 #ifndef JLM_LLVM_IR_CFG_HPP
6 #define JLM_LLVM_IR_CFG_HPP
7 
10 #include <jlm/llvm/ir/cfg-node.hpp>
11 #include <jlm/llvm/ir/types.hpp>
12 #include <jlm/llvm/ir/variable.hpp>
13 #include <jlm/rvsdg/operation.hpp>
14 #include <jlm/util/common.hpp>
15 
16 namespace jlm::llvm
17 {
18 
19 class clg_node;
20 class BasicBlock;
21 class InterProceduralGraphModule;
22 class ThreeAddressCode;
23 
26 class Argument final : public Variable
27 {
28 public:
29  ~Argument() noexcept override;
30 
32  const std::string & name,
33  std::shared_ptr<const jlm::rvsdg::Type> type,
34  const AttributeSet & attributes)
35  : Variable(std::move(type), name),
37  {}
38 
39  Argument(const std::string & name, std::shared_ptr<const jlm::rvsdg::Type> type)
40  : Variable(std::move(type), name)
41  {}
42 
44  const std::string & name,
45  std::unique_ptr<jlm::rvsdg::Type> type,
46  const AttributeSet & attributes)
47  : Variable(std::move(type), name),
49  {}
50 
51  const AttributeSet &
52  attributes() const noexcept
53  {
54  return attributes_;
55  }
56 
57  static std::unique_ptr<Argument>
59  const std::string & name,
60  std::shared_ptr<const jlm::rvsdg::Type> type,
61  const AttributeSet & attributes)
62  {
63  return std::make_unique<Argument>(name, std::move(type), attributes);
64  }
65 
66  static std::unique_ptr<Argument>
67  create(const std::string & name, std::shared_ptr<const jlm::rvsdg::Type> type)
68  {
69  return create(name, std::move(type), {});
70  }
71 
72 private:
74 };
75 
76 class EntryNode final : public ControlFlowGraphNode
77 {
78 public:
79  ~EntryNode() noexcept override;
80 
83  {}
84 
85  size_t
86  narguments() const noexcept
87  {
88  return arguments_.size();
89  }
90 
91  const llvm::Argument *
92  argument(size_t index) const
93  {
94  JLM_ASSERT(index < narguments());
95  return arguments_[index].get();
96  }
97 
99  append_argument(std::unique_ptr<llvm::Argument> arg)
100  {
101  arguments_.push_back(std::move(arg));
102  return arguments_.back().get();
103  }
104 
105  std::vector<llvm::Argument *>
106  arguments() const noexcept
107  {
108  std::vector<llvm::Argument *> arguments;
109  for (auto & argument : arguments_)
110  arguments.push_back(argument.get());
111 
112  return arguments;
113  }
114 
115 private:
116  std::vector<std::unique_ptr<llvm::Argument>> arguments_;
117 };
118 
119 class ExitNode final : public ControlFlowGraphNode
120 {
121 public:
122  ~ExitNode() noexcept override;
123 
126  {}
127 
128  size_t
129  nresults() const noexcept
130  {
131  return results_.size();
132  }
133 
134  const Variable *
135  result(size_t index) const
136  {
137  JLM_ASSERT(index < nresults());
138  return results_[index];
139  }
140 
141  inline void
143  {
144  results_.push_back(v);
145  }
146 
147  const std::vector<const Variable *>
148  results() const noexcept
149  {
150  return results_;
151  }
152 
153 private:
154  std::vector<const Variable *> results_;
155 };
156 
157 class ControlFlowGraph final
158 {
159  using iterator =
162  const BasicBlock,
163  std::unordered_set<std::unique_ptr<BasicBlock>>::const_iterator>;
164 
165 public:
166  ~ControlFlowGraph() noexcept = default;
167 
169 
171 
173 
175  operator=(const ControlFlowGraph &) = delete;
176 
178  operator=(ControlFlowGraph &&) = delete;
179 
180  inline const_iterator
181  begin() const
182  {
183  return const_iterator(nodes_.begin());
184  }
185 
186  inline iterator
188  {
189  return iterator(nodes_.begin());
190  }
191 
192  inline const_iterator
193  end() const
194  {
195  return const_iterator(nodes_.end());
196  }
197 
198  inline iterator
199  end()
200  {
201  return iterator(nodes_.end());
202  }
203 
204  EntryNode *
205  entry() const noexcept
206  {
207  return entry_.get();
208  }
209 
210  ExitNode *
211  exit() const noexcept
212  {
213  return exit_.get();
214  }
215 
216  inline BasicBlock *
217  add_node(std::unique_ptr<BasicBlock> bb)
218  {
219  auto tmp = bb.get();
220  nodes_.insert(std::move(bb));
221  return tmp;
222  }
223 
226  {
227  std::unique_ptr<BasicBlock> up(bb);
228  auto it = nodes_.find(up);
229  up.release();
230  return iterator(it);
231  }
232 
235 
237  remove_node(BasicBlock * bb);
238 
239  inline size_t
240  nnodes() const noexcept
241  {
242  return nodes_.size();
243  }
244 
245  [[nodiscard]] InterProceduralGraphModule &
246  module() const noexcept
247  {
248  return module_;
249  }
250 
252  fcttype() const
253  {
254  std::vector<std::shared_ptr<const jlm::rvsdg::Type>> arguments;
255  for (size_t n = 0; n < entry()->narguments(); n++)
256  arguments.push_back(entry()->argument(n)->Type());
257 
258  std::vector<std::shared_ptr<const jlm::rvsdg::Type>> results;
259  for (size_t n = 0; n < exit()->nresults(); n++)
260  results.push_back(exit()->result(n)->Type());
261 
262  return rvsdg::FunctionType(arguments, results);
263  }
264 
265  static std::unique_ptr<ControlFlowGraph>
267  {
268  return std::make_unique<ControlFlowGraph>(im);
269  }
270 
271  static std::string
272  ToAscii(const ControlFlowGraph & controlFlowGraph);
273 
274 private:
275  static std::string
276  ToAscii(const EntryNode & entryNode);
277 
278  static std::string
279  ToAscii(const ExitNode & exitNode);
280 
281  static std::string
282  ToAscii(
283  const BasicBlock & basicBlock,
284  const std::unordered_map<ControlFlowGraphNode *, std::string> & labels);
285 
286  static std::string
288  const ControlFlowGraphNode & node,
289  const std::unordered_map<ControlFlowGraphNode *, std::string> & labels);
290 
291  static std::unordered_map<ControlFlowGraphNode *, std::string>
292  CreateLabels(const std::vector<ControlFlowGraphNode *> & nodes);
293 
295  std::unique_ptr<ExitNode> exit_;
296  std::unique_ptr<EntryNode> entry_;
297  std::unordered_set<std::unique_ptr<BasicBlock>> nodes_;
298 };
299 
300 std::vector<ControlFlowGraphNode *>
301 postorder(const ControlFlowGraph & cfg);
302 
303 std::vector<ControlFlowGraphNode *>
305 
314 std::vector<ControlFlowGraphNode *>
315 breadth_first(const ControlFlowGraph & cfg);
316 
317 size_t
318 ntacs(const ControlFlowGraph & cfg);
319 
320 }
321 
322 #endif
Function argument.
Definition: cfg.hpp:27
static std::unique_ptr< Argument > create(const std::string &name, std::shared_ptr< const jlm::rvsdg::Type > type)
Definition: cfg.hpp:67
Argument(const std::string &name, std::shared_ptr< const jlm::rvsdg::Type > type)
Definition: cfg.hpp:39
~Argument() noexcept override
Argument(const std::string &name, std::unique_ptr< jlm::rvsdg::Type > type, const AttributeSet &attributes)
Definition: cfg.hpp:43
static std::unique_ptr< Argument > create(const std::string &name, std::shared_ptr< const jlm::rvsdg::Type > type, const AttributeSet &attributes)
Definition: cfg.hpp:58
AttributeSet attributes_
Definition: cfg.hpp:73
const AttributeSet & attributes() const noexcept
Definition: cfg.hpp:52
ControlFlowGraph & cfg() const noexcept
Definition: cfg-node.hpp:106
rvsdg::FunctionType fcttype() const
Definition: cfg.hpp:252
static std::string ToAscii(const ControlFlowGraph &controlFlowGraph)
Definition: cfg.cpp:62
static std::unique_ptr< ControlFlowGraph > create(InterProceduralGraphModule &im)
Definition: cfg.hpp:266
const_iterator begin() const
Definition: cfg.hpp:181
EntryNode * entry() const noexcept
Definition: cfg.hpp:205
static ControlFlowGraph::iterator remove_node(ControlFlowGraph::iterator &it)
Definition: cfg.cpp:34
ControlFlowGraph::iterator find_node(BasicBlock *bb)
Definition: cfg.hpp:225
ExitNode * exit() const noexcept
Definition: cfg.hpp:211
std::unique_ptr< EntryNode > entry_
Definition: cfg.hpp:296
static std::unordered_map< ControlFlowGraphNode *, std::string > CreateLabels(const std::vector< ControlFlowGraphNode * > &nodes)
Definition: cfg.cpp:166
const_iterator end() const
Definition: cfg.hpp:193
static std::string CreateTargets(const ControlFlowGraphNode &node, const std::unordered_map< ControlFlowGraphNode *, std::string > &labels)
Definition: cfg.cpp:148
~ControlFlowGraph() noexcept=default
InterProceduralGraphModule & module_
Definition: cfg.hpp:294
BasicBlock * add_node(std::unique_ptr< BasicBlock > bb)
Definition: cfg.hpp:217
size_t nnodes() const noexcept
Definition: cfg.hpp:240
std::unordered_set< std::unique_ptr< BasicBlock > > nodes_
Definition: cfg.hpp:297
InterProceduralGraphModule & module() const noexcept
Definition: cfg.hpp:246
util::PtrIterator< BasicBlock, std::unordered_set< std::unique_ptr< BasicBlock > >::iterator > iterator
Definition: cfg.hpp:160
std::unique_ptr< ExitNode > exit_
Definition: cfg.hpp:295
util::PtrIterator< const BasicBlock, std::unordered_set< std::unique_ptr< BasicBlock > >::const_iterator > const_iterator
Definition: cfg.hpp:163
llvm::Argument * append_argument(std::unique_ptr< llvm::Argument > arg)
Definition: cfg.hpp:99
size_t narguments() const noexcept
Definition: cfg.hpp:86
std::vector< llvm::Argument * > arguments() const noexcept
Definition: cfg.hpp:106
std::vector< std::unique_ptr< llvm::Argument > > arguments_
Definition: cfg.hpp:116
const llvm::Argument * argument(size_t index) const
Definition: cfg.hpp:92
~EntryNode() noexcept override
std::vector< const Variable * > results_
Definition: cfg.hpp:154
const Variable * result(size_t index) const
Definition: cfg.hpp:135
const std::vector< const Variable * > results() const noexcept
Definition: cfg.hpp:148
~ExitNode() noexcept override
void append_result(const Variable *v)
Definition: cfg.hpp:142
size_t nresults() const noexcept
Definition: cfg.hpp:129
const std::string & name() const noexcept
Definition: variable.hpp:50
const jlm::rvsdg::Type & type() const noexcept
Definition: variable.hpp:56
const std::shared_ptr< const jlm::rvsdg::Type > Type() const noexcept
Definition: variable.hpp:62
Function type class.
#define JLM_ASSERT(x)
Definition: common.hpp:16
Global memory state passed between functions.
std::vector< ControlFlowGraphNode * > breadth_first(const ControlFlowGraph &cfg)
Definition: cfg.cpp:233
std::vector< ControlFlowGraphNode * > postorder(const ControlFlowGraph &cfg)
Definition: cfg.cpp:194
size_t ntacs(const AggregationNode &root)
std::vector< ControlFlowGraphNode * > reverse_postorder(const ControlFlowGraph &cfg)
Definition: cfg.cpp:225