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