My Project
Instructions.hpp
1 #ifndef MEMOIR_INSTRUCTIONS_H
2 #define MEMOIR_INSTRUCTIONS_H
3 
4 #include <cstddef>
5 
6 #include "llvm/IR/Function.h"
7 #include "llvm/IR/Instruction.h"
8 #include "llvm/IR/Instructions.h"
9 #include "llvm/IR/Module.h"
10 #include "llvm/Support/raw_ostream.h"
11 
12 #include "memoir/support/DataTypes.hpp"
13 
14 #include "memoir/utility/FunctionNames.hpp"
15 
16 #include "memoir/ir/Keywords.hpp"
17 #include "memoir/ir/Types.hpp"
18 
19 /*
20  * MemOIR Instructions and a wrapper of an LLVM Instruction.
21  *
22  * Author(s): Tommy McMichen
23  * Created: December 13, 2022
24  */
25 
26 namespace llvm::memoir {
27 
28 struct CollectionType;
29 
30 // Abstract MemOIR Instruction
31 struct MemOIRInst {
32 public:
33  static MemOIRInst *get(llvm::Instruction &I);
34  static bool is_mutator(MemOIRInst &I);
35  static void invalidate();
36 
37  llvm::Function &getCalledFunction() const;
38 
39  llvm::Module *getModule() const;
40  llvm::Function *getFunction() const;
41  llvm::BasicBlock *getParent() const;
42  llvm::CallInst &getCallInst() const;
43  llvm::Value &asValue() const;
44 
45  MemOIR_Func getKind() const;
46 
47  bool has_keywords() const;
48 
49  template <typename KeywordTy>
50  std::optional<KeywordTy> get_keyword() const;
51 
52  llvm::iterator_range<keyword_iterator> keywords() const;
53  keyword_iterator kw_begin() const;
54  keyword_iterator kw_end() const;
55 
56  explicit operator llvm::Value *() {
57  return &this->getCallInst();
58  }
59  explicit operator llvm::Value &() {
60  return this->getCallInst();
61  }
62  explicit operator llvm::Instruction *() {
63  return &this->getCallInst();
64  }
65  explicit operator llvm::Instruction &() {
66  return this->getCallInst();
67  }
68 
69  friend std::ostream &operator<<(std::ostream &os, const MemOIRInst &I);
70  friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
71  const MemOIRInst &I);
72  virtual std::string toString() const = 0;
73 
74  virtual ~MemOIRInst() = default;
75 
76 protected:
77  llvm::CallInst &call_inst;
78 
79  static Map<llvm::Instruction *, MemOIRInst *> *llvm_to_memoir;
80 
81  MemOIRInst(llvm::CallInst &call_inst) : call_inst(call_inst) {}
82 };
83 
84 // Types.
85 struct TypeInst : public MemOIRInst {
86 public:
87  virtual Type &getType() const = 0;
88 
89  static bool classof(const MemOIRInst *I) {
90  return
91 #define HANDLE_TYPE_INST(ENUM, FUNC, CLASS) \
92  (I->getKind() == MemOIR_Func::ENUM) ||
93 #include "memoir/ir/Instructions.def"
94  false;
95  };
96 
97 protected:
98  TypeInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
99 
100  friend struct MemOIRInst;
101 };
102 
103 struct UInt64TypeInst : public TypeInst {
104 public:
105  Type &getType() const override;
106 
107  static bool classof(const MemOIRInst *I) {
108  return (I->getKind() == MemOIR_Func::UINT64_TYPE);
109  };
110 
111  std::string toString() const override;
112 
113 protected:
114  UInt64TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
115 
116  friend struct MemOIRInst;
117 };
118 
119 struct UInt32TypeInst : public TypeInst {
120 public:
121  Type &getType() const override;
122 
123  static bool classof(const MemOIRInst *I) {
124  return (I->getKind() == MemOIR_Func::UINT32_TYPE);
125  };
126 
127  std::string toString() const override;
128 
129 protected:
130  UInt32TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
131 
132  friend struct MemOIRInst;
133 };
134 
135 struct UInt16TypeInst : public TypeInst {
136 public:
137  Type &getType() const override;
138 
139  static bool classof(const MemOIRInst *I) {
140  return (I->getKind() == MemOIR_Func::UINT16_TYPE);
141  };
142 
143  std::string toString() const override;
144 
145 protected:
146  UInt16TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
147 
148  friend struct MemOIRInst;
149 };
150 
151 struct UInt8TypeInst : public TypeInst {
152 public:
153  Type &getType() const override;
154 
155  static bool classof(const MemOIRInst *I) {
156  return (I->getKind() == MemOIR_Func::UINT8_TYPE);
157  };
158 
159  std::string toString() const override;
160 
161 protected:
162  UInt8TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
163 
164  friend struct MemOIRInst;
165 };
166 
167 struct UInt2TypeInst : public TypeInst {
168 public:
169  Type &getType() const override;
170 
171  static bool classof(const MemOIRInst *I) {
172  return (I->getKind() == MemOIR_Func::UINT2_TYPE);
173  };
174 
175  std::string toString() const override;
176 
177 protected:
178  UInt2TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
179 
180  friend struct MemOIRInst;
181 };
182 
183 struct Int64TypeInst : public TypeInst {
184 public:
185  Type &getType() const override;
186 
187  static bool classof(const MemOIRInst *I) {
188  return (I->getKind() == MemOIR_Func::INT64_TYPE);
189  };
190 
191  std::string toString() const override;
192 
193 protected:
194  Int64TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
195 
196  friend struct MemOIRInst;
197 };
198 
199 struct Int32TypeInst : public TypeInst {
200 public:
201  Type &getType() const override;
202 
203  static bool classof(const MemOIRInst *I) {
204  return (I->getKind() == MemOIR_Func::INT32_TYPE);
205  };
206 
207  std::string toString() const override;
208 
209 protected:
210  Int32TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
211 
212  friend struct MemOIRInst;
213 };
214 
215 struct Int16TypeInst : public TypeInst {
216 public:
217  Type &getType() const override;
218 
219  static bool classof(const MemOIRInst *I) {
220  return (I->getKind() == MemOIR_Func::INT16_TYPE);
221  };
222 
223  std::string toString() const override;
224 
225 protected:
226  Int16TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
227 
228  friend struct MemOIRInst;
229 };
230 
231 struct Int8TypeInst : public TypeInst {
232 public:
233  Type &getType() const override;
234 
235  static bool classof(const MemOIRInst *I) {
236  return (I->getKind() == MemOIR_Func::INT8_TYPE);
237  };
238 
239  std::string toString() const override;
240 
241 protected:
242  Int8TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
243 
244  friend struct MemOIRInst;
245 };
246 
247 struct Int2TypeInst : public TypeInst {
248 public:
249  Type &getType() const override;
250 
251  static bool classof(const MemOIRInst *I) {
252  return (I->getKind() == MemOIR_Func::INT2_TYPE);
253  };
254 
255  std::string toString() const override;
256 
257 protected:
258  Int2TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
259 
260  friend struct MemOIRInst;
261 };
262 
263 struct BoolTypeInst : public TypeInst {
264 public:
265  Type &getType() const override;
266 
267  static bool classof(const MemOIRInst *I) {
268  return (I->getKind() == MemOIR_Func::BOOL_TYPE);
269  };
270 
271  std::string toString() const override;
272 
273 protected:
274  BoolTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
275 
276  friend struct MemOIRInst;
277 };
278 
279 struct FloatTypeInst : public TypeInst {
280 public:
281  Type &getType() const override;
282 
283  static bool classof(const MemOIRInst *I) {
284  return (I->getKind() == MemOIR_Func::FLOAT_TYPE);
285  };
286 
287  std::string toString() const override;
288 
289 protected:
290  FloatTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
291 
292  friend struct MemOIRInst;
293 };
294 
295 struct DoubleTypeInst : public TypeInst {
296 public:
297  Type &getType() const override;
298 
299  static bool classof(const MemOIRInst *I) {
300  return (I->getKind() == MemOIR_Func::DOUBLE_TYPE);
301  };
302 
303  std::string toString() const override;
304 
305 protected:
306  DoubleTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
307 
308  friend struct MemOIRInst;
309 };
310 
311 struct PointerTypeInst : public TypeInst {
312 public:
313  Type &getType() const override;
314 
315  static bool classof(const MemOIRInst *I) {
316  return (I->getKind() == MemOIR_Func::POINTER_TYPE);
317  };
318 
319  std::string toString() const override;
320 
321 protected:
322  PointerTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
323 
324  friend struct MemOIRInst;
325 };
326 
327 struct VoidTypeInst : public TypeInst {
328 public:
329  Type &getType() const override;
330 
331  static bool classof(const MemOIRInst *I) {
332  return (I->getKind() == MemOIR_Func::VOID_TYPE);
333  };
334 
335  std::string toString() const override;
336 
337 protected:
338  VoidTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
339 
340  friend struct MemOIRInst;
341 };
342 
343 struct ReferenceTypeInst : public TypeInst {
344 public:
345  Type &getType() const override;
346  Type &getReferencedType() const;
347  llvm::Value &getReferencedTypeOperand() const;
348  llvm::Use &getReferencedTypeOperandAsUse() const;
349 
350  static bool classof(const MemOIRInst *I) {
351  return (I->getKind() == MemOIR_Func::REFERENCE_TYPE);
352  };
353 
354  std::string toString() const override;
355 
356 protected:
357  ReferenceTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
358 
359  friend struct MemOIRInst;
360 };
361 
362 #if 0
363 struct DefineTypeInst : public TypeInst {
364 public:
365  Type &getType() const override;
366 
367  std::string getName() const;
368  llvm::Value &getNameOperand() const;
369  llvm::Use &getNameOperandAsUse() const;
370 
371  llvm::Value &getTypeOperand() const;
372  llvm::Use &getTypeOperandAsUse() const;
373 
374  static bool classof(const MemOIRInst *I) {
375  return (I->getKind() == MemOIR_Func::DEFINE_TYPE);
376  };
377 
378  std::string toString() const override;
379 
380 protected:
381  DefineTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
382 
383  friend struct MemOIRInst;
384 };
385 
386 struct LookupTypeInst : public TypeInst {
387 public:
388  Type &getType() const override;
389 
390  std::string getName() const;
391  llvm::Value &getNameOperand() const;
392  llvm::Use &getNameOperandAsUse() const;
393 
394  static bool classof(const MemOIRInst *I) {
395  return (I->getKind() == MemOIR_Func::LOOKUP_TYPE);
396  };
397 
398  std::string toString() const override;
399 
400 protected:
401  LookupTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
402 
403  friend struct MemOIRInst;
404 };
405 #endif
406 
407 struct TupleTypeInst : public TypeInst {
408 public:
409  Type &getType() const override;
410 
411  unsigned getNumberOfFields() const;
412  llvm::Value &getNumberOfFieldsOperand() const;
413  llvm::Use &getNumberOfFieldsOperandAsUse() const;
414 
415  Type &getFieldType(unsigned field_index) const;
416  llvm::Value &getFieldTypeOperand(unsigned field_index) const;
417  llvm::Use &getFieldTypeOperandAsUse(unsigned field_index) const;
418 
419  static bool classof(const MemOIRInst *I) {
420  return (I->getKind() == MemOIR_Func::TUPLE_TYPE);
421  };
422 
423  std::string toString() const override;
424 
425 protected:
426  TupleTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
427 
428  friend struct MemOIRInst;
429 };
430 
431 struct ArrayTypeInst : public TypeInst {
432 public:
433  Type &getType() const override;
434 
435  Type &getElementType() const;
436  llvm::Value &getElementTypeOperand() const;
437  llvm::Use &getElementTypeOperandAsUse() const;
438 
439  size_t getLength() const;
440  llvm::Value &getLengthOperand() const;
441  llvm::Use &getLengthOperandAsUse() const;
442 
443  static bool classof(const MemOIRInst *I) {
444  return (I->getKind() == MemOIR_Func::ARRAY_TYPE);
445  };
446 
447  std::string toString() const override;
448 
449 protected:
450  ArrayTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
451 
452  friend struct MemOIRInst;
453 };
454 
455 struct AssocTypeInst : public TypeInst {
456 public:
457  Type &getType() const override;
458  Type &getKeyType() const;
459  llvm::Value &getKeyOperand() const;
460  llvm::Use &getKeyOperandAsUse() const;
461  Type &getValueType() const;
462  llvm::Value &getValueOperand() const;
463  llvm::Use &getValueOperandAsUse() const;
464 
465  static bool classof(const MemOIRInst *I) {
466  return (I->getKind() == MemOIR_Func::ASSOC_ARRAY_TYPE);
467  };
468 
469  std::string toString() const override;
470 
471 protected:
472  AssocTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
473 
474  friend struct MemOIRInst;
475 };
476 using AssocArrayTypeInst = struct AssocTypeInst;
477 
478 struct SequenceTypeInst : public TypeInst {
479 public:
480  Type &getType() const override;
481  Type &getElementType() const;
482  llvm::Value &getElementOperand() const;
483  llvm::Use &getElementOperandAsUse() const;
484 
485  static bool classof(const MemOIRInst *I) {
486  return (I->getKind() == MemOIR_Func::SEQUENCE_TYPE);
487  };
488 
489  std::string toString() const override;
490 
491 protected:
492  SequenceTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
493 
494  friend struct MemOIRInst;
495 };
496 
497 // Allocations
498 struct AllocInst : public MemOIRInst {
499 public:
500  llvm::Value &getAllocation() const;
501 
502  Type &getType() const;
503  llvm::Value &getTypeOperand() const;
504  llvm::Use &getTypeOperandAsUse() const;
505 
506  using size_iterator = llvm::User::value_op_iterator;
507  llvm::iterator_range<size_iterator> sizes();
508  size_iterator sizes_begin();
509  size_iterator sizes_end();
510 
511  using const_size_iterator = llvm::User::const_value_op_iterator;
512  llvm::iterator_range<const_size_iterator> sizes() const;
513  const_size_iterator sizes_begin() const;
514  const_size_iterator sizes_end() const;
515 
516  using size_op_iterator = llvm::User::op_iterator;
517  llvm::iterator_range<size_op_iterator> size_operands();
518  size_op_iterator size_ops_begin();
519  size_op_iterator size_ops_end();
520 
521  using const_size_op_iterator = llvm::User::const_op_iterator;
522  llvm::iterator_range<const_size_op_iterator> size_operands() const;
523  const_size_op_iterator size_ops_begin() const;
524  const_size_op_iterator size_ops_end() const;
525 
526  static bool classof(const MemOIRInst *I) {
527  return
528 #define HANDLE_ALLOC_INST(ENUM, FUNC, CLASS) \
529  (I->getKind() == MemOIR_Func::ENUM) ||
530 #include "memoir/ir/Instructions.def"
531  false;
532  };
533 
534  std::string toString() const override;
535 
536 protected:
537  AllocInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
538 
539  friend struct MemOIRInst;
540 };
541 
542 // Accesses
543 struct AccessInst : public MemOIRInst {
544 public:
545  Type &getObjectType() const;
546  Type &getElementType() const;
547 
548  virtual llvm::Value &getObject() const = 0;
549  virtual llvm::Use &getObjectAsUse() const = 0;
550 
551  using index_iterator = llvm::User::value_op_iterator;
552  llvm::iterator_range<index_iterator> indices();
553  index_iterator indices_begin();
554  index_iterator indices_end();
555 
556  using const_index_iterator = llvm::User::const_value_op_iterator;
557  llvm::iterator_range<const_index_iterator> indices() const;
558  const_index_iterator indices_begin() const;
559  const_index_iterator indices_end() const;
560 
561  using index_op_iterator = llvm::User::op_iterator;
562  llvm::iterator_range<index_op_iterator> index_operands();
563  index_op_iterator index_operands_begin();
564  index_op_iterator index_operands_end();
565 
566  using const_index_op_iterator = llvm::User::const_op_iterator;
567  llvm::iterator_range<const_index_op_iterator> index_operands() const;
568  const_index_op_iterator index_operands_begin() const;
569  const_index_op_iterator index_operands_end() const;
570 
577  Option<size_t> match_offsets(llvm::ArrayRef<unsigned> offsets) const;
578 
579  static bool classof(const MemOIRInst *I) {
580  return (
581 #define HANDLE_ACCESS_INST(ENUM, FUNC, CLASS) \
582  (I->getKind() == MemOIR_Func::ENUM) ||
583 #include "memoir/ir/Instructions.def"
584  false);
585  };
586 
587 protected:
588  AccessInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
589 
590  friend struct MemOIRInst;
591 };
592 
593 struct ReadInst : public AccessInst {
594 public:
595  llvm::Value &getValueRead() const;
596 
597  llvm::Value &getObject() const override;
598  llvm::Use &getObjectAsUse() const override;
599 
600  static bool classof(const MemOIRInst *I) {
601  return
602 #define HANDLE_READ_INST(ENUM, FUNC, CLASS) \
603  (I->getKind() == MemOIR_Func::ENUM) ||
604 #include "memoir/ir/Instructions.def"
605  false;
606  };
607 
608  std::string toString() const override;
609 
610 protected:
611  ReadInst(llvm::CallInst &call_inst) : AccessInst(call_inst) {}
612 
613  friend struct MemOIRInst;
614 };
615 
619 struct GetInst : public AccessInst {
620 public:
621  llvm::Value &getNestedObject() const;
622 
623  llvm::Value &getObject() const override;
624  llvm::Use &getObjectAsUse() const override;
625 
626  static bool classof(const MemOIRInst *I) {
627  return I->getKind() == MemOIR_Func::GET;
628  };
629 
630  std::string toString() const override;
631 
632 protected:
633  GetInst(llvm::CallInst &call_inst) : AccessInst(call_inst) {}
634 
635  friend struct MemOIRInst;
636 };
637 
638 struct CopyInst : public AccessInst {
639  llvm::Value &getResult() const;
640 
641  llvm::Value &getObject() const override;
642  llvm::Use &getObjectAsUse() const override;
643 
644  static bool classof(const MemOIRInst *I) {
645  return I->getKind() == MemOIR_Func::COPY;
646  }
647 
648  std::string toString() const override;
649 
650 protected:
651  CopyInst(llvm::CallInst &call_inst) : AccessInst(call_inst) {}
652 
653  friend struct MemOIRInst;
654 };
655 
656 struct SizeInst : public AccessInst {
657 public:
658  llvm::Value &getSize() const;
659 
660  llvm::Value &getObject() const override;
661  llvm::Use &getObjectAsUse() const override;
662 
663  static bool classof(const MemOIRInst *I) {
664  return I->getKind() == MemOIR_Func::SIZE;
665  };
666 
667  std::string toString() const override;
668 
669 protected:
670  SizeInst(llvm::CallInst &call_inst) : AccessInst(call_inst) {}
671 
672  friend struct MemOIRInst;
673 };
674 
675 // Instructions that apply functional updates to an object
676 struct UpdateInst : public AccessInst {
677 public:
678  llvm::Value &getResult() const;
679 
680  static bool classof(const MemOIRInst *I) {
681  return
682 #define HANDLE_UPDATE_INST(ENUM, FUNC, CLASS) \
683  (I->getKind() == MemOIR_Func::ENUM) ||
684 #include "memoir/ir/Instructions.def"
685  false;
686  }
687 
688 protected:
689  UpdateInst(llvm::CallInst &call_inst) : AccessInst(call_inst) {}
690 
691  friend struct MemOIRInst;
692 };
693 
694 struct WriteInst : public UpdateInst {
695 public:
696  llvm::Value &getResult() const;
697 
698  llvm::Value &getValueWritten() const;
699  llvm::Use &getValueWrittenAsUse() const;
700 
701  llvm::Value &getObject() const override;
702  llvm::Use &getObjectAsUse() const override;
703 
704  static bool classof(const MemOIRInst *I) {
705  return
706 #define HANDLE_WRITE_INST(ENUM, FUNC, CLASS) \
707  (I->getKind() == MemOIR_Func::ENUM) ||
708 #include "memoir/ir/Instructions.def"
709  false;
710  };
711 
712  std::string toString() const override;
713 
714 protected:
715  WriteInst(llvm::CallInst &call_inst) : UpdateInst(call_inst) {}
716 
717  friend struct MemOIRInst;
718 };
719 
720 struct InsertInst : public UpdateInst {
721 public:
722  llvm::Value &getObject() const override;
723  llvm::Use &getObjectAsUse() const override;
724 
725  static bool classof(const MemOIRInst *I) {
726  return I->getKind() == MemOIR_Func::INSERT;
727  }
728 
729  std::string toString() const override;
730 
731 protected:
732  InsertInst(llvm::CallInst &call_inst) : UpdateInst(call_inst) {}
733 
734  friend struct MemOIRInst;
735 };
736 
737 struct RemoveInst : public UpdateInst {
738 public:
739  llvm::Value &getObject() const override;
740  llvm::Use &getObjectAsUse() const override;
741 
742  static bool classof(const MemOIRInst *I) {
743  return I->getKind() == MemOIR_Func::REMOVE;
744  };
745 
746  std::string toString() const override;
747 
748 protected:
749  RemoveInst(llvm::CallInst &call_inst) : UpdateInst(call_inst) {}
750 
751  friend struct MemOIRInst;
752 };
753 
754 struct ClearInst : public UpdateInst {
755 public:
756  llvm::Value &getObject() const override;
757  llvm::Use &getObjectAsUse() const override;
758 
759  static bool classof(const MemOIRInst *I) {
760  return (I->getKind() == MemOIR_Func::CLEAR);
761  };
762 
763  std::string toString() const override;
764 
765 protected:
766  ClearInst(llvm::CallInst &call_inst) : UpdateInst(call_inst) {}
767 
768  friend struct MemOIRInst;
769 };
770 // ==============================================================
771 
772 // Assoc operations
773 struct HasInst : public AccessInst {
774 public:
775  llvm::Value &getResult() const;
776 
777  llvm::Value &getObject() const override;
778  llvm::Use &getObjectAsUse() const override;
779 
780  static bool classof(const MemOIRInst *I) {
781  return (I->getKind() == MemOIR_Func::HAS);
782  };
783 
784  std::string toString() const override;
785 
786 protected:
787  HasInst(llvm::CallInst &call_inst) : AccessInst(call_inst) {}
788 
789  friend struct MemOIRInst;
790 };
791 
792 struct KeysInst : public AccessInst {
793 public:
794  llvm::Value &getResult() const;
795 
796  llvm::Value &getObject() const override;
797  llvm::Use &getObjectAsUse() const override;
798 
799  static bool classof(const MemOIRInst *I) {
800  return (I->getKind() == MemOIR_Func::KEYS);
801  };
802 
803  std::string toString() const override;
804 
805 protected:
806  KeysInst(llvm::CallInst &call_inst) : AccessInst(call_inst) {}
807 
808  friend struct MemOIRInst;
809 };
810 
811 // Fold operations.
812 struct FoldInst : public AccessInst {
813 public:
819  static FoldInst *get_single_fold(llvm::Function &func);
820 
821  llvm::Value &getResult() const;
822 
823  bool isReverse() const;
824 
825  llvm::Value &getInitial() const;
826  llvm::Use &getInitialAsUse() const;
827 
828  llvm::Value &getObject() const override;
829  llvm::Use &getObjectAsUse() const override;
830 
831  llvm::Function &getBody() const;
832  llvm::Value &getBodyOperand() const;
833  llvm::Use &getBodyOperandAsUse() const;
834 
835  std::optional<ClosedKeyword> getClosed() const;
836 
837  using iterator = ClosedKeyword::iterator;
838  llvm::iterator_range<iterator> closed();
839  iterator closed_begin();
840  iterator closed_end();
841 
842  using operand_iterator = ClosedKeyword::operand_iterator;
843  llvm::iterator_range<operand_iterator> closed_operands();
844  operand_iterator closed_ops_begin();
845  operand_iterator closed_ops_end();
846 
847  using const_iterator = ClosedKeyword::const_iterator;
848  llvm::iterator_range<const_iterator> closed() const;
849  const_iterator closed_begin() const;
850  const_iterator closed_end() const;
851 
852  using const_operand_iterator = ClosedKeyword::const_operand_iterator;
853  llvm::iterator_range<const_operand_iterator> closed_operands() const;
854  const_operand_iterator closed_ops_begin() const;
855  const_operand_iterator closed_ops_end() const;
856 
860  llvm::Argument &getAccumulatorArgument() const;
861 
865  llvm::Argument &getIndexArgument() const;
866 
874  llvm::Argument *getElementArgument() const;
875 
883  llvm::Argument *getClosedArgument(llvm::Use &use) const;
884 
890  llvm::Use *getOperandForArgument(llvm::Argument &arg) const;
891 
892  std::string toString() const override;
893 
894  static bool classof(const MemOIRInst *I) {
895  return
896 #define HANDLE_FOLD_INST(ENUM, FUNC, CLASS) \
897  (I->getKind() == MemOIR_Func::ENUM) ||
898 #include "memoir/ir/Instructions.def"
899  false;
900  };
901 
902 protected:
903  FoldInst(llvm::CallInst &call_inst) : AccessInst(call_inst) {}
904 
905  friend struct MemOIRInst;
906 };
907 
908 // SSA/readonce operations.
909 struct UsePHIInst : public MemOIRInst {
910 public:
911  llvm::Value &getResult() const;
912 
913  llvm::Value &getUsed() const;
914  llvm::Use &getUsedAsUse() const;
915 
916  static bool classof(const MemOIRInst *I) {
917  return (I->getKind() == MemOIR_Func::USE_PHI);
918  };
919 
920  std::string toString() const override;
921 
922 protected:
923  UsePHIInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
924 
925  friend struct MemOIRInst;
926 };
927 
928 struct EndInst : public MemOIRInst {
929 public:
930  llvm::Value &getValue() const;
931 
932  static bool classof(const MemOIRInst *I) {
933  return (I->getKind() == MemOIR_Func::END);
934  };
935 
936  std::string toString() const override;
937 
938 protected:
939  EndInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
940 
941  friend struct MemOIRInst;
942 };
943 
944 struct RetPHIInst : public MemOIRInst {
945 public:
946  llvm::Value &getResult() const;
947 
948  llvm::Value &getInput() const;
949  llvm::Use &getInputAsUse() const;
950 
955  llvm::Function *getCalledFunction() const;
956  llvm::Value &getCalledOperand() const;
957  llvm::Use &getCalledOperandAsUse() const;
958 
959  // TODO: add methods for decoding the metadata.
960 
961  static bool classof(const MemOIRInst *I) {
962  return (I->getKind() == MemOIR_Func::RET_PHI);
963  };
964 
965  std::string toString() const override;
966 
967 protected:
968  RetPHIInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
969 
970  friend struct MemOIRInst;
971 };
972 
973 // Deletion operations
974 struct DeleteInst : public MemOIRInst {
975 public:
976  llvm::Value &getObject() const;
977  llvm::Use &getObjectAsUse() const;
978 
979  static bool classof(const MemOIRInst *I) {
980  return (I->getKind() == MemOIR_Func::DELETE);
981  };
982 
983  std::string toString() const override;
984 
985 protected:
986  DeleteInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
987 
988  friend struct MemOIRInst;
989 };
990 
991 // Type checking
992 struct AssertTypeInst : public MemOIRInst {
993 public:
994  Type &getType() const;
995  llvm::Value &getTypeOperand() const;
996  llvm::Use &getTypeOperandAsUse() const;
997 
998  llvm::Value &getObject() const;
999  llvm::Use &getObjectAsUse() const;
1000 
1001  static bool classof(const MemOIRInst *I) {
1002  return (I->getKind() == MemOIR_Func::ASSERT_TYPE);
1003  };
1004 
1005  std::string toString() const override;
1006 
1007 protected:
1008  AssertTypeInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
1009 
1010  friend struct MemOIRInst;
1011 };
1012 
1013 struct ReturnTypeInst : public MemOIRInst {
1014 public:
1015  Type &getType() const;
1016  llvm::Value &getTypeOperand() const;
1017  llvm::Use &getTypeOperandAsUse() const;
1018 
1019  static bool classof(const MemOIRInst *I) {
1020  return (I->getKind() == MemOIR_Func::SET_RETURN_TYPE);
1021  };
1022 
1023  std::string toString() const override;
1024 
1025 protected:
1026  ReturnTypeInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
1027 
1028  friend struct MemOIRInst;
1029 };
1030 
1031 } // namespace llvm::memoir
1032 
1033 #endif
Definition: Instructions.hpp:543
Option< size_t > match_offsets(llvm::ArrayRef< unsigned > offsets) const
Definition: AccessInsts.cpp:162
Definition: Instructions.hpp:498
Definition: Instructions.hpp:431
Definition: Instructions.hpp:992
Definition: Instructions.hpp:455
Definition: Instructions.hpp:263
Definition: Instructions.hpp:754
Definition: Instructions.hpp:638
Definition: Instructions.hpp:974
Definition: Instructions.hpp:295
Definition: Instructions.hpp:928
Definition: Instructions.hpp:279
Definition: Instructions.hpp:812
llvm::Argument & getAccumulatorArgument() const
Definition: FoldInst.cpp:132
static FoldInst * get_single_fold(llvm::Function &func)
Definition: FoldInst.cpp:11
llvm::Argument & getIndexArgument() const
Definition: FoldInst.cpp:136
llvm::Use * getOperandForArgument(llvm::Argument &arg) const
Definition: FoldInst.cpp:214
llvm::Argument * getElementArgument() const
Definition: FoldInst.cpp:140
llvm::Argument * getClosedArgument(llvm::Use &use) const
Definition: FoldInst.cpp:175
Definition: Instructions.hpp:619
Definition: Instructions.hpp:773
Definition: Instructions.hpp:720
Definition: Instructions.hpp:215
Definition: Instructions.hpp:247
Definition: Instructions.hpp:199
Definition: Instructions.hpp:183
Definition: Instructions.hpp:231
Definition: Instructions.hpp:792
Definition: Instructions.hpp:31
Definition: Instructions.hpp:311
Definition: Instructions.hpp:593
Definition: Instructions.hpp:343
Definition: Instructions.hpp:737
Definition: Instructions.hpp:944
llvm::Function * getCalledFunction() const
Definition: SSAInsts.cpp:20
Definition: Instructions.hpp:1013
Definition: Instructions.hpp:478
Definition: Instructions.hpp:656
Definition: Instructions.hpp:407
Definition: Instructions.hpp:85
Definition: Types.hpp:51
Definition: Instructions.hpp:135
Definition: Instructions.hpp:167
Definition: Instructions.hpp:119
Definition: Instructions.hpp:103
Definition: Instructions.hpp:151
Definition: Instructions.hpp:676
Definition: Instructions.hpp:909
Definition: Instructions.hpp:327
Definition: Instructions.hpp:694
Definition: Keywords.hpp:73