Jlm
tac.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2014 2015 Nico Reißmann <nico.reissmann@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #ifndef JLM_LLVM_IR_TAC_HPP
7 #define JLM_LLVM_IR_TAC_HPP
8 
10 #include <jlm/rvsdg/operation.hpp>
11 #include <jlm/util/common.hpp>
12 
13 #include <list>
14 #include <memory>
15 #include <vector>
16 
17 namespace jlm::llvm
18 {
19 
20 class ThreeAddressCode;
21 
22 class ThreeAddressCodeVariable final : public Variable
23 {
24 public:
25  ~ThreeAddressCodeVariable() noexcept override;
26 
29  std::shared_ptr<const jlm::rvsdg::Type> type,
30  const std::string & name)
31  : Variable(std::move(type), name),
32  tac_(tac)
33  {}
34 
35  [[nodiscard]] llvm::ThreeAddressCode *
36  tac() const noexcept
37  {
38  return tac_;
39  }
40 
41  static std::unique_ptr<ThreeAddressCodeVariable>
44  std::shared_ptr<const jlm::rvsdg::Type> type,
45  const std::string & name)
46  {
47  return std::make_unique<ThreeAddressCodeVariable>(tac, std::move(type), name);
48  }
49 
50 private:
52 };
53 
54 class ThreeAddressCode final
55 {
56 public:
57  ~ThreeAddressCode() noexcept = default;
58 
60  std::unique_ptr<rvsdg::SimpleOperation> operation,
61  const std::vector<const Variable *> & operands);
62 
64  std::unique_ptr<rvsdg::SimpleOperation> operation,
65  const std::vector<const Variable *> & operands,
66  const std::vector<std::string> & names);
67 
69  std::unique_ptr<rvsdg::SimpleOperation> operation,
70  const std::vector<const Variable *> & operands,
71  std::vector<std::unique_ptr<ThreeAddressCodeVariable>> results);
72 
74 
76 
78  operator=(const llvm::ThreeAddressCode &) = delete;
79 
81  operator=(llvm::ThreeAddressCode &&) = delete;
82 
83  inline const rvsdg::SimpleOperation &
84  operation() const noexcept
85  {
86  return *util::assertedCast<rvsdg::SimpleOperation>(operation_.get());
87  }
88 
89  inline size_t
90  noperands() const noexcept
91  {
92  return operands_.size();
93  }
94 
95  inline const Variable *
96  operand(size_t index) const noexcept
97  {
98  JLM_ASSERT(index < operands_.size());
99  return operands_[index];
100  }
101 
102  inline size_t
103  nresults() const noexcept
104  {
105  return results_.size();
106  }
107 
108  [[nodiscard]] const ThreeAddressCodeVariable *
109  result(size_t index) const noexcept
110  {
111  JLM_ASSERT(index < results_.size());
112  return results_[index].get();
113  }
114 
115  /*
116  FIXME: I am really not happy with this function exposing
117  the results, but we need these results for the SSA destruction.
118  */
119  std::vector<std::unique_ptr<ThreeAddressCodeVariable>>
121  {
122  return std::move(results_);
123  }
124 
125  void
126  replace(const rvsdg::SimpleOperation & operation, const std::vector<const Variable *> & operands);
127 
128  void
129  convert(const rvsdg::SimpleOperation & operation, const std::vector<const Variable *> & operands);
130 
131  static std::string
132  ToAscii(const ThreeAddressCode & threeAddressCode);
133 
134  static std::unique_ptr<llvm::ThreeAddressCode>
136  std::unique_ptr<rvsdg::SimpleOperation> operation,
137  const std::vector<const Variable *> & operands)
138  {
139  return std::make_unique<llvm::ThreeAddressCode>(std::move(operation), operands);
140  }
141 
142  static std::unique_ptr<llvm::ThreeAddressCode>
144  std::unique_ptr<rvsdg::SimpleOperation> operation,
145  const std::vector<const Variable *> & operands,
146  const std::vector<std::string> & names)
147  {
148  return std::make_unique<llvm::ThreeAddressCode>(std::move(operation), operands, names);
149  }
150 
151  static std::unique_ptr<llvm::ThreeAddressCode>
153  std::unique_ptr<rvsdg::SimpleOperation> operation,
154  const std::vector<const Variable *> & operands,
155  std::vector<std::unique_ptr<ThreeAddressCodeVariable>> results)
156  {
157  return std::make_unique<llvm::ThreeAddressCode>(
158  std::move(operation),
159  operands,
160  std::move(results));
161  }
162 
163 private:
164  void
165  create_results(const rvsdg::SimpleOperation & operation, const std::vector<std::string> & names)
166  {
167  JLM_ASSERT(names.size() == operation.nresults());
168 
169  for (size_t n = 0; n < operation.nresults(); n++)
170  {
171  auto & type = operation.result(n);
172  results_.push_back(ThreeAddressCodeVariable::create(this, type, names[n]));
173  }
174  }
175 
176  static std::vector<std::string>
177  create_names(size_t nnames)
178  {
179  static size_t c = 0;
180  std::vector<std::string> names;
181  for (size_t n = 0; n < nnames; n++)
182  names.push_back(jlm::util::strfmt("tv", c++));
183 
184  return names;
185  }
186 
187  std::vector<const Variable *> operands_;
188  std::unique_ptr<rvsdg::Operation> operation_;
189  std::vector<std::unique_ptr<ThreeAddressCodeVariable>> results_;
190 };
191 
192 template<class T>
193 static inline bool
195 {
196  return tac && is<T>(tac->operation());
197 }
198 
199 /* FIXME: Replace all occurences of tacsvector_t with ThreeAddressCodeList
200  and then remove tacsvector_t.
201 */
202 typedef std::vector<std::unique_ptr<llvm::ThreeAddressCode>> tacsvector_t;
203 
205 {
206 public:
207  typedef std::list<ThreeAddressCode *>::const_iterator const_iterator;
208  typedef std::list<ThreeAddressCode *>::const_reverse_iterator const_reverse_iterator;
209 
210  ~ThreeAddressCodeList() noexcept;
211 
212  ThreeAddressCodeList() = default;
213 
215 
217  : tacs_(std::move(other.tacs_))
218  {}
219 
221  operator=(const ThreeAddressCodeList &) = delete;
222 
224  operator=(ThreeAddressCodeList && other) noexcept
225  {
226  if (this == &other)
227  return *this;
228 
229  for (const auto & tac : tacs_)
230  delete tac;
231 
232  tacs_.clear();
233  tacs_ = std::move(other.tacs_);
234 
235  return *this;
236  }
237 
238  inline const_iterator
239  begin() const noexcept
240  {
241  return tacs_.begin();
242  }
243 
245  rbegin() const noexcept
246  {
247  return tacs_.rbegin();
248  }
249 
250  inline const_iterator
251  end() const noexcept
252  {
253  return tacs_.end();
254  }
255 
257  rend() const noexcept
258  {
259  return tacs_.rend();
260  }
261 
262  inline ThreeAddressCode *
263  insert_before(const const_iterator & it, std::unique_ptr<llvm::ThreeAddressCode> tac)
264  {
265  return *tacs_.insert(it, tac.release());
266  }
267 
268  inline void
270  {
271  tacs_.insert(it, tl.begin(), tl.end());
272  }
273 
274  inline void
275  append_last(std::unique_ptr<llvm::ThreeAddressCode> tac)
276  {
277  tacs_.push_back(tac.release());
278  }
279 
280  inline void
281  append_first(std::unique_ptr<llvm::ThreeAddressCode> tac)
282  {
283  tacs_.push_front(tac.release());
284  }
285 
286  inline void
288  {
289  tacs_.insert(tacs_.begin(), tl.begin(), tl.end());
290  tl.tacs_.clear();
291  }
292 
293  inline size_t
294  ntacs() const noexcept
295  {
296  return tacs_.size();
297  }
298 
299  inline ThreeAddressCode *
300  first() const noexcept
301  {
302  return ntacs() != 0 ? tacs_.front() : nullptr;
303  }
304 
305  inline ThreeAddressCode *
306  last() const noexcept
307  {
308  return ntacs() != 0 ? tacs_.back() : nullptr;
309  }
310 
311  std::unique_ptr<ThreeAddressCode>
312  pop_first() noexcept
313  {
314  std::unique_ptr<ThreeAddressCode> tac(tacs_.front());
315  tacs_.pop_front();
316  return tac;
317  }
318 
319  std::unique_ptr<ThreeAddressCode>
320  pop_last() noexcept
321  {
322  std::unique_ptr<ThreeAddressCode> tac(tacs_.back());
323  tacs_.pop_back();
324  return tac;
325  }
326 
327  inline void
329  {
330  delete tacs_.front();
331  tacs_.pop_front();
332  }
333 
334  inline void
336  {
337  delete tacs_.back();
338  tacs_.pop_back();
339  }
340 
341 private:
342  std::list<ThreeAddressCode *> tacs_;
343 };
344 
345 }
346 
347 #endif
~ThreeAddressCodeList() noexcept
Definition: tac.cpp:15
const_iterator end() const noexcept
Definition: tac.hpp:251
const_iterator begin() const noexcept
Definition: tac.hpp:239
ThreeAddressCode * first() const noexcept
Definition: tac.hpp:300
void append_first(std::unique_ptr< llvm::ThreeAddressCode > tac)
Definition: tac.hpp:281
std::unique_ptr< ThreeAddressCode > pop_last() noexcept
Definition: tac.hpp:320
ThreeAddressCodeList & operator=(ThreeAddressCodeList &&other) noexcept
Definition: tac.hpp:224
void insert_before(const const_iterator &it, ThreeAddressCodeList &tl)
Definition: tac.hpp:269
const_reverse_iterator rbegin() const noexcept
Definition: tac.hpp:245
ThreeAddressCodeList & operator=(const ThreeAddressCodeList &)=delete
std::unique_ptr< ThreeAddressCode > pop_first() noexcept
Definition: tac.hpp:312
std::list< ThreeAddressCode * >::const_reverse_iterator const_reverse_iterator
Definition: tac.hpp:208
std::list< ThreeAddressCode * > tacs_
Definition: tac.hpp:342
void append_first(ThreeAddressCodeList &tl)
Definition: tac.hpp:287
ThreeAddressCode * last() const noexcept
Definition: tac.hpp:306
ThreeAddressCode * insert_before(const const_iterator &it, std::unique_ptr< llvm::ThreeAddressCode > tac)
Definition: tac.hpp:263
std::list< ThreeAddressCode * >::const_iterator const_iterator
Definition: tac.hpp:207
size_t ntacs() const noexcept
Definition: tac.hpp:294
void append_last(std::unique_ptr< llvm::ThreeAddressCode > tac)
Definition: tac.hpp:275
const_reverse_iterator rend() const noexcept
Definition: tac.hpp:257
llvm::ThreeAddressCode * tac_
Definition: tac.hpp:51
llvm::ThreeAddressCode * tac() const noexcept
Definition: tac.hpp:36
static std::unique_ptr< ThreeAddressCodeVariable > create(llvm::ThreeAddressCode *tac, std::shared_ptr< const jlm::rvsdg::Type > type, const std::string &name)
Definition: tac.hpp:42
~ThreeAddressCodeVariable() noexcept override
void create_results(const rvsdg::SimpleOperation &operation, const std::vector< std::string > &names)
Definition: tac.hpp:165
const ThreeAddressCodeVariable * result(size_t index) const noexcept
Definition: tac.hpp:109
std::unique_ptr< rvsdg::Operation > operation_
Definition: tac.hpp:188
std::vector< const Variable * > operands_
Definition: tac.hpp:187
static std::unique_ptr< llvm::ThreeAddressCode > create(std::unique_ptr< rvsdg::SimpleOperation > operation, const std::vector< const Variable * > &operands, const std::vector< std::string > &names)
Definition: tac.hpp:143
void replace(const rvsdg::SimpleOperation &operation, const std::vector< const Variable * > &operands)
Definition: tac.cpp:108
static std::unique_ptr< llvm::ThreeAddressCode > create(std::unique_ptr< rvsdg::SimpleOperation > operation, const std::vector< const Variable * > &operands)
Definition: tac.hpp:135
const Variable * operand(size_t index) const noexcept
Definition: tac.hpp:96
static std::unique_ptr< llvm::ThreeAddressCode > create(std::unique_ptr< rvsdg::SimpleOperation > operation, const std::vector< const Variable * > &operands, std::vector< std::unique_ptr< ThreeAddressCodeVariable >> results)
Definition: tac.hpp:152
void convert(const rvsdg::SimpleOperation &operation, const std::vector< const Variable * > &operands)
Definition: tac.cpp:93
size_t nresults() const noexcept
Definition: tac.hpp:103
std::vector< std::unique_ptr< ThreeAddressCodeVariable > > results_
Definition: tac.hpp:189
static std::string ToAscii(const ThreeAddressCode &threeAddressCode)
Definition: tac.cpp:120
const rvsdg::SimpleOperation & operation() const noexcept
Definition: tac.hpp:84
std::vector< std::unique_ptr< ThreeAddressCodeVariable > > results()
Definition: tac.hpp:120
~ThreeAddressCode() noexcept=default
size_t noperands() const noexcept
Definition: tac.hpp:90
static std::vector< std::string > create_names(size_t nnames)
Definition: tac.hpp:177
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
const std::shared_ptr< const rvsdg::Type > & result(size_t index) const noexcept
Definition: operation.cpp:36
size_t nresults() const noexcept
Definition: operation.cpp:30
#define JLM_ASSERT(x)
Definition: common.hpp:16
Global memory state passed between functions.
std::vector< std::unique_ptr< llvm::ThreeAddressCode > > tacsvector_t
Definition: tac.hpp:202
static bool is(const AggregationNode *node)
static std::string type(const Node *n)
Definition: view.cpp:255
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
Definition: node.hpp:1049
static std::string strfmt(Args... args)
Definition: strfmt.hpp:35