My Project
Keywords.hpp
1 #ifndef MEMOIR_KEYWORDS_H
2 #define MEMOIR_KEYWORDS_H
3 
4 #include <string>
5 #include <type_traits>
6 
7 #include "llvm/IR/Constants.h"
8 #include "llvm/IR/GlobalVariable.h"
9 #include "llvm/IR/User.h"
10 
11 #include "memoir/support/Assert.hpp"
12 
13 namespace llvm::memoir {
14 
15 struct Keyword {
16 public:
17  using iterator = llvm::User::value_op_iterator;
18  using operand_iterator = llvm::User::op_iterator;
19  using const_iterator = llvm::User::const_value_op_iterator;
20  using const_operand_iterator = llvm::User::const_op_iterator;
21 
25  static bool is_keyword(llvm::Value &V);
26  static bool is_keyword(llvm::Value *V);
27 
31  template <
32  typename KeywordTy,
33  std::enable_if_t<std::is_base_of_v<Keyword, KeywordTy>, bool> = true>
34  static llvm::ConstantDataArray &get_llvm(llvm::LLVMContext &C) {
35  std::string name =
36  std::string(Keyword::PREFIX) + std::string(KeywordTy::NAME);
37 
38  auto *data = llvm::ConstantDataArray::getString(C, name);
39 
40  return MEMOIR_SANITIZE(dyn_cast_or_null<llvm::ConstantDataArray>(data),
41  "Failed to create keyword as LLVM constant.");
42  }
43 
47  llvm::Use &getAsUse() const;
48 
49  llvm::iterator_range<iterator> values();
50  iterator begin();
51  iterator end();
52 
53  llvm::iterator_range<operand_iterator> operands();
54  operand_iterator op_begin();
55  operand_iterator op_end();
56 
57  llvm::iterator_range<const_iterator> values() const;
58  const_iterator begin() const;
59  const_iterator end() const;
60 
61  llvm::iterator_range<const_operand_iterator> operands() const;
62  const_operand_iterator op_begin() const;
63  const_operand_iterator op_end() const;
64 
65  Keyword(llvm::Use &use) : use(&use) {}
66 
67  static const char *PREFIX;
68 
69 protected:
70  llvm::Use *use;
71 };
72 
74 public:
75  using value_type = Keyword;
76 
77  keyword_iterator(llvm::Use *op) : op(op) {}
78 
79  value_type operator*() const;
80 
81  keyword_iterator &operator++();
82 
83  friend bool operator==(const keyword_iterator &lhs,
84  const keyword_iterator &rhs) {
85  return lhs.op == rhs.op;
86  }
87 
88  llvm::Use *asUse() const {
89  return this->op;
90  }
91 
92 protected:
93  llvm::Use *op;
94 };
95 
96 #define CLASSOF_IMPL() \
97  static bool classof(const Keyword &kw) { \
98  auto *value = kw.getAsUse().get(); \
99  auto *data = dyn_cast<llvm::ConstantDataSequential>(value); \
100  if (auto *global = dyn_cast<llvm::GlobalVariable>(value)) { \
101  auto *init = global->getInitializer(); \
102  data = dyn_cast<llvm::ConstantDataSequential>(init); \
103  } \
104  if (not data) { \
105  return false; \
106  } \
107  auto str = data->getAsCString(); \
108  return str.ends_with(NAME); \
109  }
110 
111 struct ClosedKeyword : public Keyword {
112 public:
113  llvm::iterator_range<Keyword::iterator> args();
114  Keyword::iterator args_begin();
115  Keyword::iterator args_end();
116 
117  llvm::iterator_range<Keyword::operand_iterator> arg_operands();
118  Keyword::operand_iterator arg_ops_begin();
119  Keyword::operand_iterator arg_ops_end();
120 
121  CLASSOF_IMPL()
122 
123  ClosedKeyword(llvm::Use &use) : Keyword(use) {}
124 
125 protected:
126  static const char *NAME;
127 
128  friend struct Keyword;
129 };
130 
131 struct InputKeyword : public Keyword {
132 public:
133  llvm::Value &getInput() const;
134  llvm::Use &getInputAsUse() const;
135 
136  llvm::iterator_range<Keyword::iterator> indices();
137  Keyword::iterator indices_begin();
138  Keyword::iterator indices_end();
139 
140  llvm::iterator_range<Keyword::operand_iterator> index_operands();
141  Keyword::operand_iterator index_ops_begin();
142  Keyword::operand_iterator index_ops_end();
143 
144  CLASSOF_IMPL()
145 
146  InputKeyword(llvm::Use &use) : Keyword(use) {}
147 
148 protected:
149  static const char *NAME;
150 
151  friend struct Keyword;
152 };
153 
154 struct RangeKeyword : public Keyword {
155 public:
156  llvm::Value &getBegin() const;
157  llvm::Use &getBeginAsUse() const;
158 
159  llvm::Value &getEnd() const;
160  llvm::Use &getEndAsUse() const;
161 
162  CLASSOF_IMPL()
163 
164  RangeKeyword(llvm::Use &use) : Keyword(use) {}
165 
166 protected:
167  static const char *NAME;
168 
169  friend struct Keyword;
170 };
171 
172 struct ValueKeyword : public Keyword {
173 public:
174  llvm::Value &getValue() const;
175  llvm::Use &getValueAsUse() const;
176 
177  CLASSOF_IMPL()
178 
179  ValueKeyword(llvm::Use &use) : Keyword(use) {}
180 
181 protected:
182  static const char *NAME;
183 
184  friend struct Keyword;
185 };
186 
187 struct SelectionKeyword : public Keyword {
188 public:
189  std::string getSelection() const;
190  llvm::Value &getSelectionOperand() const;
191  llvm::Use &getSelectionOperandAsUse() const;
192 
193  CLASSOF_IMPL()
194 
195  SelectionKeyword(llvm::Use &use) : Keyword(use) {}
196 
197 protected:
198  static const char *NAME;
199 
200  friend struct Keyword;
201 };
202 
203 struct ReverseKeyword : public Keyword {
204 public:
205  CLASSOF_IMPL()
206 
207  ReverseKeyword(llvm::Use &use) : Keyword(use) {}
208 
209 protected:
210  static const char *NAME;
211 
212  friend struct Keyword;
213 };
214 
215 struct ADENoShareKeyword : public Keyword {
216 public:
217  llvm::iterator_range<Keyword::iterator> indices();
218  Keyword::iterator indices_begin();
219  Keyword::iterator indices_end();
220 
221  llvm::iterator_range<Keyword::operand_iterator> index_operands();
222  Keyword::operand_iterator index_ops_begin();
223  Keyword::operand_iterator index_ops_end();
224 
225  CLASSOF_IMPL()
226 
227  ADENoShareKeyword(llvm::Use &use) : Keyword(use) {}
228 
229 protected:
230  static const char *NAME;
231 
232  friend struct Keyword;
233 };
234 
235 } // namespace llvm::memoir
236 
237 #endif // MEMOIR_KEYWORDS_H
Definition: Keywords.hpp:215
Definition: Keywords.hpp:111
Definition: Keywords.hpp:131
Definition: Keywords.hpp:15
static bool is_keyword(llvm::Value &V)
Definition: Keywords.cpp:18
llvm::Use & getAsUse() const
Definition: Keywords.cpp:59
static llvm::ConstantDataArray & get_llvm(llvm::LLVMContext &C)
Definition: Keywords.hpp:34
Definition: Keywords.hpp:154
Definition: Keywords.hpp:203
Definition: Keywords.hpp:187
Definition: Keywords.hpp:172
Definition: Keywords.hpp:73