Jlm
Loading...
Searching...
No Matches
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
11#include <jlm/llvm/ir/types.hpp>
14#include <jlm/util/common.hpp>
16
17namespace jlm::llvm
18{
19
20class clg_node;
21class BasicBlock;
22class InterProceduralGraphModule;
23class ThreeAddressCode;
24
27class Argument final : public Variable
28{
29public:
30 ~Argument() noexcept override;
31
33 const std::string & name,
34 std::shared_ptr<const jlm::rvsdg::Type> type,
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,
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,
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
73private:
75};
76
77class EntryNode final : public ControlFlowGraphNode
78{
79public:
80 ~EntryNode() noexcept override;
81
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
116private:
117 std::vector<std::unique_ptr<llvm::Argument>> arguments_;
118};
119
120class ExitNode final : public ControlFlowGraphNode
121{
122public:
123 ~ExitNode() noexcept override;
124
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
154private:
155 std::vector<const Variable *> results_;
156};
157
159{
160 using iterator =
163 const BasicBlock,
164 std::unordered_set<std::unique_ptr<BasicBlock>>::const_iterator>;
165
166public:
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
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
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
293private:
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
319std::vector<ControlFlowGraphNode *>
320postorder(const ControlFlowGraph & cfg);
321
322std::vector<ControlFlowGraphNode *>
324
333std::vector<ControlFlowGraphNode *>
335
336size_t
337ntacs(const ControlFlowGraph & cfg);
338
339}
340
341#endif
std::vector< rvsdg::Node * > nodes
util::HashSet< rvsdg::Output * > arguments
Function argument.
Definition cfg.hpp:28
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
const AttributeSet & attributes() const noexcept
Definition cfg.hpp:53
Argument(const std::string &name, std::shared_ptr< const jlm::rvsdg::Type > type)
Definition cfg.hpp:40
~Argument() noexcept override
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::unique_ptr< jlm::rvsdg::Type > type, const AttributeSet &attributes)
Definition cfg.hpp:44
AttributeSet attributes_
Definition cfg.hpp:74
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
const_iterator begin() const
Definition cfg.hpp:182
ExitNode * exit() const noexcept
Definition cfg.hpp:212
static ControlFlowGraph::iterator remove_node(ControlFlowGraph::iterator &it)
Definition cfg.cpp:36
ControlFlowGraph::iterator find_node(BasicBlock *bb)
Definition cfg.hpp:226
std::unique_ptr< EntryNode > entry_
Definition cfg.hpp:315
EntryNode * entry() const noexcept
Definition cfg.hpp:206
InterProceduralGraphModule & module() const noexcept
Definition cfg.hpp:247
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
BasicBlock * add_node(std::unique_ptr< BasicBlock > bb)
Definition cfg.hpp:218
~ControlFlowGraph() noexcept=default
static std::unique_ptr< ControlFlowGraph > create(InterProceduralGraphModule &im)
Definition cfg.hpp:267
InterProceduralGraphModule & module_
Definition cfg.hpp:313
size_t nnodes() const noexcept
Definition cfg.hpp:241
std::unordered_set< std::unique_ptr< BasicBlock > > nodes_
Definition cfg.hpp:316
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
const llvm::Argument * argument(size_t index) const
Definition cfg.hpp:93
size_t narguments() const noexcept
Definition cfg.hpp:87
std::vector< std::unique_ptr< llvm::Argument > > arguments_
Definition cfg.hpp:117
llvm::Argument * append_argument(std::unique_ptr< llvm::Argument > arg)
Definition cfg.hpp:100
std::vector< llvm::Argument * > arguments() const noexcept
Definition cfg.hpp:107
~EntryNode() noexcept override
std::vector< const Variable * > results_
Definition cfg.hpp:155
~ExitNode() noexcept override
void append_result(const Variable *v)
Definition cfg.hpp:143
size_t nresults() const noexcept
Definition cfg.hpp:130
const std::vector< const Variable * > results() const noexcept
Definition cfg.hpp:149
const Variable * result(size_t index) const
Definition cfg.hpp:136
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