Instructions.hpp
1 #ifndef COMMON_INSTRUCTIONS_H
2 #define COMMON_INSTRUCTIONS_H
3 #pragma once
4 
5 #include <cstddef>
6 
7 #include "llvm/IR/Function.h"
8 #include "llvm/IR/Instruction.h"
9 #include "llvm/IR/Instructions.h"
10 #include "llvm/IR/Module.h"
11 #include "llvm/Support/raw_ostream.h"
12 
13 #include "memoir/support/InternalDatatypes.hpp"
14 
15 #include "memoir/utility/FunctionNames.hpp"
16 
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 &getFunction() const;
38  llvm::CallInst &getCallInst() const;
39  llvm::Function &getLLVMFunction() const;
40  llvm::Module *getModule() const;
41  llvm::BasicBlock *getParent() const;
42  MemOIR_Func getKind() const;
43 
44  explicit operator llvm::Value *() {
45  return &this->getCallInst();
46  }
47  explicit operator llvm::Value &() {
48  return this->getCallInst();
49  }
50  explicit operator llvm::Instruction *() {
51  return &this->getCallInst();
52  }
53  explicit operator llvm::Instruction &() {
54  return this->getCallInst();
55  }
56 
57  friend std::ostream &operator<<(std::ostream &os, const MemOIRInst &I);
58  friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
59  const MemOIRInst &I);
60  virtual std::string toString(std::string indent = "") const = 0;
61 
62  virtual ~MemOIRInst() = default;
63 
64 protected:
65  llvm::CallInst &call_inst;
66 
67  static map<llvm::Instruction *, MemOIRInst *> *llvm_to_memoir;
68 
69  MemOIRInst(llvm::CallInst &call_inst) : call_inst(call_inst) {};
70 };
71 
72 // Types.
73 struct TypeInst : public MemOIRInst {
74 public:
75  virtual Type &getType() const = 0;
76 
77  static bool classof(const MemOIRInst *I) {
78  return
79 #define HANDLE_TYPE_INST(ENUM, FUNC, CLASS) \
80  (I->getKind() == MemOIR_Func::ENUM) ||
81 #include "memoir/ir/Instructions.def"
82  false;
83  };
84 
85 protected:
86  TypeInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
87 
88  friend struct MemOIRInst;
89 };
90 
91 struct UInt64TypeInst : public TypeInst {
92 public:
93  Type &getType() const override;
94 
95  static bool classof(const MemOIRInst *I) {
96  return (I->getKind() == MemOIR_Func::UINT64_TYPE);
97  };
98 
99  std::string toString(std::string indent = "") const override;
100 
101 protected:
102  UInt64TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
103 
104  friend struct MemOIRInst;
105 };
106 
107 struct UInt32TypeInst : public TypeInst {
108 public:
109  Type &getType() const override;
110 
111  static bool classof(const MemOIRInst *I) {
112  return (I->getKind() == MemOIR_Func::UINT32_TYPE);
113  };
114 
115  std::string toString(std::string indent = "") const override;
116 
117 protected:
118  UInt32TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
119 
120  friend struct MemOIRInst;
121 };
122 
123 struct UInt16TypeInst : public TypeInst {
124 public:
125  Type &getType() const override;
126 
127  static bool classof(const MemOIRInst *I) {
128  return (I->getKind() == MemOIR_Func::UINT16_TYPE);
129  };
130 
131  std::string toString(std::string indent = "") const override;
132 
133 protected:
134  UInt16TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
135 
136  friend struct MemOIRInst;
137 };
138 
139 struct UInt8TypeInst : public TypeInst {
140 public:
141  Type &getType() const override;
142 
143  static bool classof(const MemOIRInst *I) {
144  return (I->getKind() == MemOIR_Func::UINT8_TYPE);
145  };
146 
147  std::string toString(std::string indent = "") const override;
148 
149 protected:
150  UInt8TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
151 
152  friend struct MemOIRInst;
153 };
154 
155 struct UInt2TypeInst : public TypeInst {
156 public:
157  Type &getType() const override;
158 
159  static bool classof(const MemOIRInst *I) {
160  return (I->getKind() == MemOIR_Func::UINT2_TYPE);
161  };
162 
163  std::string toString(std::string indent = "") const override;
164 
165 protected:
166  UInt2TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
167 
168  friend struct MemOIRInst;
169 };
170 
171 struct Int64TypeInst : public TypeInst {
172 public:
173  Type &getType() const override;
174 
175  static bool classof(const MemOIRInst *I) {
176  return (I->getKind() == MemOIR_Func::INT64_TYPE);
177  };
178 
179  std::string toString(std::string indent = "") const override;
180 
181 protected:
182  Int64TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
183 
184  friend struct MemOIRInst;
185 };
186 
187 struct Int32TypeInst : public TypeInst {
188 public:
189  Type &getType() const override;
190 
191  static bool classof(const MemOIRInst *I) {
192  return (I->getKind() == MemOIR_Func::INT32_TYPE);
193  };
194 
195  std::string toString(std::string indent = "") const override;
196 
197 protected:
198  Int32TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
199 
200  friend struct MemOIRInst;
201 };
202 
203 struct Int16TypeInst : public TypeInst {
204 public:
205  Type &getType() const override;
206 
207  static bool classof(const MemOIRInst *I) {
208  return (I->getKind() == MemOIR_Func::INT16_TYPE);
209  };
210 
211  std::string toString(std::string indent = "") const override;
212 
213 protected:
214  Int16TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
215 
216  friend struct MemOIRInst;
217 };
218 
219 struct Int8TypeInst : public TypeInst {
220 public:
221  Type &getType() const override;
222 
223  static bool classof(const MemOIRInst *I) {
224  return (I->getKind() == MemOIR_Func::INT8_TYPE);
225  };
226 
227  std::string toString(std::string indent = "") const override;
228 
229 protected:
230  Int8TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
231 
232  friend struct MemOIRInst;
233 };
234 
235 struct Int2TypeInst : public TypeInst {
236 public:
237  Type &getType() const override;
238 
239  static bool classof(const MemOIRInst *I) {
240  return (I->getKind() == MemOIR_Func::INT2_TYPE);
241  };
242 
243  std::string toString(std::string indent = "") const override;
244 
245 protected:
246  Int2TypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
247 
248  friend struct MemOIRInst;
249 };
250 
251 struct BoolTypeInst : public TypeInst {
252 public:
253  Type &getType() const override;
254 
255  static bool classof(const MemOIRInst *I) {
256  return (I->getKind() == MemOIR_Func::BOOL_TYPE);
257  };
258 
259  std::string toString(std::string indent = "") const override;
260 
261 protected:
262  BoolTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
263 
264  friend struct MemOIRInst;
265 };
266 
267 struct FloatTypeInst : public TypeInst {
268 public:
269  Type &getType() const override;
270 
271  static bool classof(const MemOIRInst *I) {
272  return (I->getKind() == MemOIR_Func::FLOAT_TYPE);
273  };
274 
275  std::string toString(std::string indent = "") const override;
276 
277 protected:
278  FloatTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
279 
280  friend struct MemOIRInst;
281 };
282 
283 struct DoubleTypeInst : public TypeInst {
284 public:
285  Type &getType() const override;
286 
287  static bool classof(const MemOIRInst *I) {
288  return (I->getKind() == MemOIR_Func::DOUBLE_TYPE);
289  };
290 
291  std::string toString(std::string indent = "") const override;
292 
293 protected:
294  DoubleTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
295 
296  friend struct MemOIRInst;
297 };
298 
299 struct PointerTypeInst : public TypeInst {
300 public:
301  Type &getType() const override;
302 
303  static bool classof(const MemOIRInst *I) {
304  return (I->getKind() == MemOIR_Func::POINTER_TYPE);
305  };
306 
307  std::string toString(std::string indent = "") const override;
308 
309 protected:
310  PointerTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
311 
312  friend struct MemOIRInst;
313 };
314 
315 struct ReferenceTypeInst : public TypeInst {
316 public:
317  Type &getType() const override;
318  Type &getReferencedType() const;
319  llvm::Value &getReferencedTypeOperand() const;
320  llvm::Use &getReferencedTypeOperandAsUse() const;
321 
322  static bool classof(const MemOIRInst *I) {
323  return (I->getKind() == MemOIR_Func::REFERENCE_TYPE);
324  };
325 
326  std::string toString(std::string indent = "") const override;
327 
328 protected:
329  ReferenceTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
330 
331  friend struct MemOIRInst;
332 };
333 
335 public:
336  Type &getType() const override;
337  std::string getName() const;
338  llvm::Value &getNameOperand() const;
339  llvm::Use &getNameOperandAsUse() const;
340 
341  unsigned getNumberOfFields() const;
342  llvm::Value &getNumberOfFieldsOperand() const;
343  llvm::Use &getNumberOfFieldsOperandAsUse() const;
344 
345  Type &getFieldType(unsigned field_index) const;
346  llvm::Value &getFieldTypeOperand(unsigned field_index) const;
347  llvm::Use &getFieldTypeOperandAsUse(unsigned field_index) const;
348 
349  static bool classof(const MemOIRInst *I) {
350  return (I->getKind() == MemOIR_Func::DEFINE_STRUCT_TYPE);
351  };
352 
353  std::string toString(std::string indent = "") const override;
354 
355 protected:
356  DefineStructTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
357 
358  friend struct MemOIRInst;
359 };
360 
361 struct StructTypeInst : public TypeInst {
362 public:
363  Type &getType() const override;
364  std::string getName() const;
365  llvm::Value &getNameOperand() const;
366  llvm::Use &getNameOperandAsUse() const;
367 
368  static bool classof(const MemOIRInst *I) {
369  return (I->getKind() == MemOIR_Func::STRUCT_TYPE);
370  };
371 
372  std::string toString(std::string indent = "") const override;
373 
374 protected:
375  StructTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
376 
377  friend struct MemOIRInst;
378 };
379 
381 public:
382  Type &getType() const override;
383  Type &getElementType() const;
384  llvm::Value &getElementTypeOperand() const;
385  llvm::Use &getElementTypeOperandAsUse() const;
386  unsigned getNumberOfDimensions() const;
387  llvm::Value &getNumberOfDimensionsOperand() const;
388  llvm::Use &getNumberOfDimensionsOperandAsUse() const;
389  size_t getLengthOfDimension(unsigned dimension_index) const;
390  llvm::Value &getLengthOfDimensionOperand(unsigned dimension_index) const;
391  llvm::Use &getLengthOfDimensionOperandAsUse(unsigned dimension_index) const;
392 
393  static bool classof(const MemOIRInst *I) {
394  return (I->getKind() == MemOIR_Func::STATIC_TENSOR_TYPE);
395  };
396 
397  std::string toString(std::string indent = "") const override;
398 
399 protected:
400  StaticTensorTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
401 
402  friend struct MemOIRInst;
403 };
404 
405 struct TensorTypeInst : public TypeInst {
406 public:
407  Type &getType() const override;
408  Type &getElementType() const;
409  llvm::Value &getElementOperand() const;
410  llvm::Use &getElementOperandAsUse() const;
411  unsigned getNumberOfDimensions() const;
412  llvm::Value &getNumberOfDimensionsOperand() const;
413  llvm::Use &getNumberOfDimensionsOperandAsUse() const;
414 
415  static bool classof(const MemOIRInst *I) {
416  return (I->getKind() == MemOIR_Func::TENSOR_TYPE);
417  };
418 
419  std::string toString(std::string indent = "") const override;
420 
421 protected:
422  TensorTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
423 
424  friend struct MemOIRInst;
425 };
426 
427 struct AssocArrayTypeInst : public TypeInst {
428 public:
429  Type &getType() const override;
430  Type &getKeyType() const;
431  llvm::Value &getKeyOperand() const;
432  llvm::Use &getKeyOperandAsUse() const;
433  Type &getValueType() const;
434  llvm::Value &getValueOperand() const;
435  llvm::Use &getValueOperandAsUse() const;
436 
437  static bool classof(const MemOIRInst *I) {
438  return (I->getKind() == MemOIR_Func::ASSOC_ARRAY_TYPE);
439  };
440 
441  std::string toString(std::string indent = "") const override;
442 
443 protected:
444  AssocArrayTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
445 
446  friend struct MemOIRInst;
447 };
448 using AssocTypeInst = struct AssocArrayTypeInst;
449 
450 struct SequenceTypeInst : public TypeInst {
451 public:
452  Type &getType() const override;
453  Type &getElementType() const;
454  llvm::Value &getElementOperand() const;
455  llvm::Use &getElementOperandAsUse() const;
456 
457  static bool classof(const MemOIRInst *I) {
458  return (I->getKind() == MemOIR_Func::SEQUENCE_TYPE);
459  };
460 
461  std::string toString(std::string indent = "") const override;
462 
463 protected:
464  SequenceTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
465 
466  friend struct MemOIRInst;
467 };
468 
469 // Allocations
470 struct AllocInst : public MemOIRInst {
471 public:
472  llvm::Value &getAllocation() const;
473  virtual Type &getType() const = 0;
474 
475  static bool classof(const MemOIRInst *I) {
476  return
477 #define HANDLE_ALLOC_INST(ENUM, FUNC, CLASS) \
478  (I->getKind() == MemOIR_Func::ENUM) ||
479 #include "memoir/ir/Instructions.def"
480  false;
481  };
482 
483 protected:
484  AllocInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
485 
486  friend struct MemOIRInst;
487 };
488 
489 struct StructAllocInst : public AllocInst {
490 public:
491  llvm::Value &getStruct() const;
492 
493  StructType &getStructType() const;
494  Type &getType() const override;
495 
496  llvm::Value &getTypeOperand() const;
497  llvm::Use &getTypeOperandAsUse() const;
498 
499  static bool classof(const MemOIRInst *I) {
500  return (I->getKind() == MemOIR_Func::ALLOCATE_STRUCT);
501  };
502 
503  std::string toString(std::string indent = "") const override;
504 
505 protected:
506  StructAllocInst(llvm::CallInst &call_inst) : AllocInst(call_inst) {}
507 
508  friend struct MemOIRInst;
509 };
510 
512 public:
513  virtual llvm::Value &getCollection() const = 0;
514  virtual CollectionType &getCollectionType() const = 0;
515 
516  static bool classof(const MemOIRInst *I) {
517  return (
518 #define HANDLE_COLLECTION_ALLOC_INST(ENUM, FUNC, CLASS) \
519  (I->getKind() == MemOIR_Func::ENUM) ||
520 #include "memoir/ir/Instructions.def"
521  false);
522  };
523 
524  Type &getType() const override;
525 
526 protected:
527  CollectionAllocInst(llvm::CallInst &call_inst) : AllocInst(call_inst) {}
528 
529  friend struct MemOIRInst;
530 };
531 
533 public:
534  llvm::Value &getCollection() const override;
535  CollectionType &getCollectionType() const override;
536 
537  Type &getElementType() const;
538  llvm::Value &getElementOperand() const;
539  llvm::Use &getElementOperandAsUse() const;
540 
541  unsigned getNumberOfDimensions() const;
542  llvm::Value &getNumberOfDimensionsOperand() const;
543  llvm::Use &getNumberOfDimensionsOperandAsUse() const;
544  llvm::Value &getLengthOfDimensionOperand(unsigned dimension_index) const;
545  llvm::Use &getLengthOfDimensionOperandAsUse(unsigned dimension_index) const;
546 
547  static bool classof(const MemOIRInst *I) {
548  return (I->getKind() == MemOIR_Func::ALLOCATE_TENSOR);
549  };
550 
551  std::string toString(std::string indent = "") const override;
552 
553 protected:
554  TensorAllocInst(llvm::CallInst &call_inst) : CollectionAllocInst(call_inst) {}
555 
556  friend struct MemOIRInst;
557 };
558 
560 public:
561  llvm::Value &getCollection() const override;
562  CollectionType &getCollectionType() const override;
563 
564  Type &getKeyType() const;
565  llvm::Value &getKeyOperand() const;
566  llvm::Use &getKeyOperandAsUse() const;
567 
568  Type &getValueType() const;
569  llvm::Value &getValueOperand() const;
570  llvm::Use &getValueOperandAsUse() const;
571 
572  static bool classof(const MemOIRInst *I) {
573  return (I->getKind() == MemOIR_Func::ALLOCATE_ASSOC_ARRAY);
574  };
575 
576  std::string toString(std::string indent = "") const override;
577 
578 protected:
579  AssocArrayAllocInst(llvm::CallInst &call_inst)
580  : CollectionAllocInst(call_inst) {}
581 
582  friend struct MemOIRInst;
583 };
584 using AssocAllocInst = struct AssocArrayAllocInst;
585 
587 public:
588  llvm::Value &getCollection() const override;
589  CollectionType &getCollectionType() const override;
590 
591  Type &getElementType() const;
592  llvm::Value &getElementOperand() const;
593  llvm::Use &getElementOperandAsUse() const;
594 
595  llvm::Value &getSizeOperand() const;
596  llvm::Use &getSizeOperandAsUse() const;
597 
598  static bool classof(const MemOIRInst *I) {
599  return (I->getKind() == MemOIR_Func::ALLOCATE_SEQUENCE);
600  };
601 
602  std::string toString(std::string indent = "") const override;
603 
604 protected:
605  SequenceAllocInst(llvm::CallInst &call_inst)
606  : CollectionAllocInst(call_inst) {}
607 
608  friend struct MemOIRInst;
609 };
610 
611 // Accesses
612 struct AccessInst : public MemOIRInst {
613 public:
614  virtual CollectionType &getCollectionType() const;
615 
616  virtual llvm::Value &getObjectOperand() const = 0;
617  virtual llvm::Use &getObjectOperandAsUse() const = 0;
618 
619  static bool classof(const MemOIRInst *I) {
620  return (
621 #define HANDLE_ACCESS_INST(ENUM, FUNC, CLASS) \
622  (I->getKind() == MemOIR_Func::ENUM) ||
623 #include "memoir/ir/Instructions.def"
624  false);
625  };
626 
627 protected:
628  AccessInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
629 
630  friend struct MemOIRInst;
631 };
632 
633 // Read Accesses
634 struct ReadInst : public AccessInst {
635 public:
636  llvm::Value &getValueRead() const;
637 
638  llvm::Value &getObjectOperand() const override;
639  llvm::Use &getObjectOperandAsUse() const override;
640 
641  static bool classof(const MemOIRInst *I) {
642  return
643 #define HANDLE_READ_INST(ENUM, FUNC, CLASS) \
644  (I->getKind() == MemOIR_Func::ENUM) ||
645 #include "memoir/ir/Instructions.def"
646  false;
647  };
648 
649 protected:
650  ReadInst(llvm::CallInst &call_inst) : AccessInst(call_inst) {}
651 
652  friend struct MemOIRInst;
653 };
654 
655 struct StructReadInst : public ReadInst {
656 public:
657  CollectionType &getCollectionType() const override;
658 
659  unsigned getFieldIndex() const;
660  llvm::Value &getFieldIndexOperand() const;
661  llvm::Use &getFieldIndexOperandAsUse() const;
662 
663  static bool classof(const MemOIRInst *I) {
664  return
665 #define HANDLE_STRUCT_READ_INST(ENUM, FUNC, CLASS) \
666  (I->getKind() == MemOIR_Func::ENUM) ||
667 #include "memoir/ir/Instructions.def"
668  false;
669  };
670 
671  std::string toString(std::string indent = "") const override;
672 
673 protected:
674  StructReadInst(llvm::CallInst &call_inst) : ReadInst(call_inst) {}
675 
676  friend struct MemOIRInst;
677 };
678 
679 struct IndexReadInst : public ReadInst {
680 public:
681  unsigned getNumberOfDimensions() const;
682  llvm::Value &getIndexOfDimension(unsigned dim_idx) const;
683  llvm::Use &getIndexOfDimensionAsUse(unsigned dim_idx) const;
684 
685  static bool classof(const MemOIRInst *I) {
686  return
687 #define HANDLE_INDEX_READ_INST(ENUM, FUNC, CLASS) \
688  (I->getKind() == MemOIR_Func::ENUM) ||
689 #include "memoir/ir/Instructions.def"
690  false;
691  };
692 
693  std::string toString(std::string indent = "") const override;
694 
695 protected:
696  IndexReadInst(llvm::CallInst &call_inst) : ReadInst(call_inst) {}
697 
698  friend struct MemOIRInst;
699 };
700 
701 struct AssocReadInst : public ReadInst {
702 public:
703  llvm::Value &getKeyOperand() const;
704  llvm::Use &getKeyOperandAsUse() const;
705 
706  static bool classof(const MemOIRInst *I) {
707  return
708 #define HANDLE_ASSOC_READ_INST(ENUM, FUNC, CLASS) \
709  (I->getKind() == MemOIR_Func::ENUM) ||
710 #include "memoir/ir/Instructions.def"
711  false;
712  };
713 
714  std::string toString(std::string indent = "") const override;
715 
716 protected:
717  AssocReadInst(llvm::CallInst &call_inst) : ReadInst(call_inst) {}
718 
719  friend struct MemOIRInst;
720 };
721 
722 // Write Accesses
723 struct WriteInst : public AccessInst {
724 public:
725  llvm::Value &getValueWritten() const;
726  llvm::Use &getValueWrittenAsUse() const;
727 
728  llvm::Value &getObjectOperand() const override;
729  llvm::Use &getObjectOperandAsUse() const override;
730 
731  static bool classof(const MemOIRInst *I) {
732  return
733 #define HANDLE_WRITE_INST(ENUM, FUNC, CLASS) \
734  (I->getKind() == MemOIR_Func::ENUM) ||
735 #include "memoir/ir/Instructions.def"
736  false;
737  };
738 
739 protected:
740  WriteInst(llvm::CallInst &call_inst) : AccessInst(call_inst) {}
741 
742  friend struct MemOIRInst;
743 };
744 
745 struct StructWriteInst : public WriteInst {
746 public:
747  CollectionType &getCollectionType() const override;
748 
749  unsigned getFieldIndex() const;
750  llvm::Value &getFieldIndexOperand() const;
751  llvm::Use &getFieldIndexOperandAsUse() const;
752 
753  static bool classof(const MemOIRInst *I) {
754  return
755 #define HANDLE_STRUCT_WRITE_INST(ENUM, FUNC, CLASS) \
756  (I->getKind() == MemOIR_Func::ENUM) ||
757 #include "memoir/ir/Instructions.def"
758  false;
759  };
760 
761  std::string toString(std::string indent = "") const override;
762 
763 protected:
764  StructWriteInst(llvm::CallInst &call_inst) : WriteInst(call_inst) {}
765 
766  friend struct MemOIRInst;
767 };
768 
769 struct IndexWriteInst : public WriteInst {
770 public:
771  llvm::Value &getCollection() const;
772 
773  unsigned getNumberOfDimensions() const;
774  llvm::Value &getIndexOfDimension(unsigned dim_idx) const;
775  llvm::Use &getIndexOfDimensionAsUse(unsigned dim_idx) const;
776 
777  static bool classof(const MemOIRInst *I) {
778  return
779 #define HANDLE_INDEX_WRITE_INST(ENUM, FUNC, CLASS) \
780  (I->getKind() == MemOIR_Func::ENUM) ||
781 #include "memoir/ir/Instructions.def"
782  false;
783  };
784 
785  std::string toString(std::string indent = "") const override;
786 
787 protected:
788  IndexWriteInst(llvm::CallInst &call_inst) : WriteInst(call_inst) {}
789 
790  friend struct MemOIRInst;
791 };
792 
793 struct AssocWriteInst : public WriteInst {
794 public:
795  llvm::Value &getCollection() const;
796 
797  llvm::Value &getKeyOperand() const;
798  llvm::Use &getKeyOperandAsUse() const;
799 
800  static bool classof(const MemOIRInst *I) {
801  return
802 #define HANDLE_ASSOC_WRITE_INST(ENUM, FUNC, CLASS) \
803  (I->getKind() == MemOIR_Func::ENUM) ||
804 #include "memoir/ir/Instructions.def"
805  false;
806  };
807 
808  std::string toString(std::string indent = "") const override;
809 
810 protected:
811  AssocWriteInst(llvm::CallInst &call_inst) : WriteInst(call_inst) {}
812 
813  friend struct MemOIRInst;
814 };
815 
816 // Nested Accesses
817 struct GetInst : public AccessInst {
818 public:
819  llvm::Value &getNestedObject() const;
820 
821  llvm::Value &getObjectOperand() const override;
822  llvm::Use &getObjectOperandAsUse() const override;
823 
824  static bool classof(const MemOIRInst *I) {
825  return
826 #define HANDLE_GET_INST(ENUM, FUNC, CLASS) \
827  (I->getKind() == MemOIR_Func::ENUM) ||
828 #include "memoir/ir/Instructions.def"
829  false;
830  };
831 
832 protected:
833  GetInst(llvm::CallInst &call_inst) : AccessInst(call_inst) {}
834 
835  friend struct MemOIRInst;
836 };
837 
838 struct StructGetInst : public GetInst {
839 public:
840  CollectionType &getCollectionType() const override;
841 
842  unsigned getFieldIndex() const;
843  llvm::Value &getFieldIndexOperand() const;
844  llvm::Use &getFieldIndexOperandAsUse() const;
845 
846  static bool classof(const MemOIRInst *I) {
847  return
848 #define HANDLE_STRUCT_GET_INST(ENUM, FUNC, CLASS) \
849  (I->getKind() == MemOIR_Func::ENUM) ||
850 #include "memoir/ir/Instructions.def"
851  false;
852  };
853 
854  std::string toString(std::string indent = "") const override;
855 
856 protected:
857  StructGetInst(llvm::CallInst &call_inst) : GetInst(call_inst) {}
858 
859  friend struct MemOIRInst;
860 };
861 
862 struct IndexGetInst : public GetInst {
863 public:
864  unsigned getNumberOfDimensions() const;
865  llvm::Value &getIndexOfDimension(unsigned dim_idx) const;
866  llvm::Use &getIndexOfDimensionAsUse(unsigned dim_idx) const;
867 
868  static bool classof(const MemOIRInst *I) {
869  return
870 #define HANDLE_INDEX_GET_INST(ENUM, FUNC, CLASS) \
871  (I->getKind() == MemOIR_Func::ENUM) ||
872 #include "memoir/ir/Instructions.def"
873  false;
874  };
875 
876  std::string toString(std::string indent = "") const override;
877 
878 protected:
879  IndexGetInst(llvm::CallInst &call_inst) : GetInst(call_inst) {}
880 
881  friend struct MemOIRInst;
882 };
883 
884 struct AssocGetInst : public GetInst {
885 public:
886  llvm::Value &getKeyOperand() const;
887  llvm::Use &getKeyOperandAsUse() const;
888 
889  static bool classof(const MemOIRInst *I) {
890  return
891 #define HANDLE_ASSOC_GET_INST(ENUM, FUNC, CLASS) \
892  (I->getKind() == MemOIR_Func::ENUM) ||
893 #include "memoir/ir/Instructions.def"
894  false;
895  };
896 
897  std::string toString(std::string indent = "") const override;
898 
899 protected:
900  AssocGetInst(llvm::CallInst &call_inst) : GetInst(call_inst) {}
901 
902  friend struct MemOIRInst;
903 };
904 
905 // Abstract insert operation.
906 struct InsertInst : public MemOIRInst {
907 public:
908  virtual llvm::Value &getResultCollection() const;
909 
910  virtual llvm::Value &getBaseCollection() const = 0;
911  virtual llvm::Use &getBaseCollectionAsUse() const = 0;
912 
913  virtual llvm::Value &getInsertionPoint() const = 0;
914  virtual llvm::Use &getInsertionPointAsUse() const = 0;
915 
916  static bool classof(const MemOIRInst *I) {
917  return
918 #define HANDLE_INSERT_INST(ENUM, FUNC, CLASS) \
919  (I->getKind() == MemOIR_Func::ENUM) ||
920 #include "memoir/ir/Instructions.def"
921  false;
922  }
923 
924  InsertInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
925 };
926 
927 // Sequence insert operations.
928 struct SeqInsertInst : public InsertInst {
929 public:
930  llvm::Value &getBaseCollection() const override;
931  llvm::Use &getBaseCollectionAsUse() const override;
932 
933  llvm::Value &getValueInserted() const;
934  llvm::Use &getValueInsertedAsUse() const;
935 
936  llvm::Value &getInsertionPoint() const override;
937  llvm::Use &getInsertionPointAsUse() const override;
938 
939  static bool classof(const MemOIRInst *I) {
940  return
941 #define HANDLE_SEQ_INSERT_INST(ENUM, FUNC, CLASS) \
942  (I->getKind() == MemOIR_Func::ENUM) ||
943 #include "memoir/ir/Instructions.def"
944  false;
945  };
946 
947  std::string toString(std::string indent = "") const override;
948 
949 protected:
950  SeqInsertInst(llvm::CallInst &call_inst) : InsertInst(call_inst) {}
951 
952  friend struct MemOIRInst;
953 };
954 
955 struct SeqInsertSeqInst : public InsertInst {
956 public:
957  llvm::Value &getBaseCollection() const override;
958  llvm::Use &getBaseCollectionAsUse() const override;
959 
960  llvm::Value &getInsertedCollection() const;
961  llvm::Use &getInsertedCollectionAsUse() const;
962 
963  llvm::Value &getInsertionPoint() const override;
964  llvm::Use &getInsertionPointAsUse() const override;
965 
966  static bool classof(const MemOIRInst *I) {
967  return (I->getKind() == MemOIR_Func::SEQ_INSERT);
968  };
969 
970  std::string toString(std::string indent = "") const override;
971 
972 protected:
973  SeqInsertSeqInst(llvm::CallInst &call_inst) : InsertInst(call_inst) {}
974 
975  friend struct MemOIRInst;
976 };
977 
978 struct RemoveInst : public MemOIRInst {
979 public:
980  virtual llvm::Value &getResultCollection() const;
981 
982  virtual llvm::Value &getBaseCollection() const = 0;
983  virtual llvm::Use &getBaseCollectionAsUse() const = 0;
984 
985  static bool classof(const MemOIRInst *I) {
986  return
987 #define HANDLE_REMOVE_INST(ENUM, FUNC, CLASS) \
988  (I->getKind() == MemOIR_Func::ENUM) ||
989 #include "memoir/ir/Instructions.def"
990  false;
991  };
992 
993  RemoveInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
994 };
995 
996 struct SeqRemoveInst : public RemoveInst {
997 public:
998  llvm::Value &getBaseCollection() const override;
999  llvm::Use &getBaseCollectionAsUse() const override;
1000 
1001  llvm::Value &getBeginIndex() const;
1002  llvm::Use &getBeginIndexAsUse() const;
1003 
1004  llvm::Value &getEndIndex() const;
1005  llvm::Use &getEndIndexAsUse() const;
1006 
1007  static bool classof(const MemOIRInst *I) {
1008  return (I->getKind() == MemOIR_Func::SEQ_REMOVE);
1009  };
1010 
1011  std::string toString(std::string indent = "") const override;
1012 
1013 protected:
1014  SeqRemoveInst(llvm::CallInst &call_inst) : RemoveInst(call_inst) {}
1015 
1016  friend struct MemOIRInst;
1017 };
1018 
1019 struct SwapInst : public MemOIRInst {
1020  llvm::Value &getResult() const;
1021 
1022  virtual llvm::Value &getIncomingCollectionFor(
1023  llvm::Value &collection) const = 0;
1024  virtual llvm::Use &getIncomingCollectionAsUseFor(
1025  llvm::Value &collection) const = 0;
1026 
1027  virtual llvm::Value &getFromCollection() const = 0;
1028  virtual llvm::Use &getFromCollectionAsUse() const = 0;
1029 
1030  virtual llvm::Value &getBeginIndex() const = 0;
1031  virtual llvm::Use &getBeginIndexAsUse() const = 0;
1032 
1033  virtual llvm::Value &getEndIndex() const = 0;
1034  virtual llvm::Use &getEndIndexAsUse() const = 0;
1035 
1036  virtual llvm::Value &getToCollection() const = 0;
1037  virtual llvm::Use &getToCollectionAsUse() const = 0;
1038 
1039  virtual llvm::Value &getToBeginIndex() const = 0;
1040  virtual llvm::Use &getToBeginIndexAsUse() const = 0;
1041 
1042  static bool classof(MemOIRInst *I) {
1043  return
1044 #define HANDLE_SWAP_INST(ENUM, FUNC, CLASS) \
1045  (I->getKind() == MemOIR_Func::ENUM) ||
1046 #include "memoir/ir/Instructions.def"
1047  false;
1048  }
1049 
1050  SwapInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
1051 };
1052 
1053 struct SeqSwapInst : public SwapInst {
1054 public:
1055  llvm::Value &getIncomingCollectionFor(llvm::Value &collection) const override;
1056  llvm::Use &getIncomingCollectionAsUseFor(
1057  llvm::Value &collection) const override;
1058 
1059  llvm::Value &getFromCollection() const override;
1060  llvm::Use &getFromCollectionAsUse() const override;
1061 
1062  llvm::Value &getBeginIndex() const override;
1063  llvm::Use &getBeginIndexAsUse() const override;
1064 
1065  llvm::Value &getEndIndex() const override;
1066  llvm::Use &getEndIndexAsUse() const override;
1067 
1068  llvm::Value &getToCollection() const override;
1069  llvm::Use &getToCollectionAsUse() const override;
1070 
1071  llvm::Value &getToBeginIndex() const override;
1072  llvm::Use &getToBeginIndexAsUse() const override;
1073 
1074  static bool classof(const MemOIRInst *I) {
1075  return (I->getKind() == MemOIR_Func::SEQ_SWAP);
1076  };
1077 
1078  std::string toString(std::string indent = "") const override;
1079 
1080 protected:
1081  SeqSwapInst(llvm::CallInst &call_inst) : SwapInst(call_inst) {}
1082 
1083  friend struct MemOIRInst;
1084 };
1085 
1086 struct SeqSwapWithinInst : public SwapInst {
1087 public:
1088  llvm::Value &getIncomingCollectionFor(llvm::Value &collection) const override;
1089  llvm::Use &getIncomingCollectionAsUseFor(
1090  llvm::Value &collection) const override;
1091 
1092  llvm::Value &getFromCollection() const override;
1093  llvm::Use &getFromCollectionAsUse() const override;
1094 
1095  llvm::Value &getBeginIndex() const override;
1096  llvm::Use &getBeginIndexAsUse() const override;
1097 
1098  llvm::Value &getEndIndex() const override;
1099  llvm::Use &getEndIndexAsUse() const override;
1100 
1101  llvm::Value &getToCollection() const override;
1102  llvm::Use &getToCollectionAsUse() const override;
1103 
1104  llvm::Value &getToBeginIndex() const override;
1105  llvm::Use &getToBeginIndexAsUse() const override;
1106 
1107  static bool classof(const MemOIRInst *I) {
1108  return (I->getKind() == MemOIR_Func::SEQ_SWAP_WITHIN);
1109  };
1110 
1111  std::string toString(std::string indent = "") const override;
1112 
1113 protected:
1114  SeqSwapWithinInst(llvm::CallInst &call_inst) : SwapInst(call_inst) {}
1115 
1116  friend struct MemOIRInst;
1117 };
1118 
1119 struct CopyInst : public MemOIRInst {
1120  virtual llvm::Value &getCopy() const;
1121 
1122  virtual llvm::Value &getCopiedCollection() const;
1123  virtual llvm::Use &getCopiedCollectionAsUse() const;
1124 
1125  static bool classof(const MemOIRInst *I) {
1126  return
1127 #define HANDLE_COPY_INST(ENUM, FUNC, CLASS) \
1128  (I->getKind() == MemOIR_Func::ENUM) ||
1129 #include "memoir/ir/Instructions.def"
1130  false;
1131  }
1132 
1133 protected:
1134  CopyInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
1135 
1136  friend struct MemOIRInst;
1137 };
1138 
1139 struct SeqCopyInst : public CopyInst {
1140 public:
1141  llvm::Value &getBeginIndex() const;
1142  llvm::Use &getBeginIndexAsUse() const;
1143 
1144  llvm::Value &getEndIndex() const;
1145  llvm::Use &getEndIndexAsUse() const;
1146 
1147  static bool classof(const MemOIRInst *I) {
1148  return (I->getKind() == MemOIR_Func::SEQ_COPY);
1149  };
1150 
1151  std::string toString(std::string indent = "") const override;
1152 
1153 protected:
1154  SeqCopyInst(llvm::CallInst &call_inst) : CopyInst(call_inst) {}
1155 
1156  friend struct MemOIRInst;
1157 };
1158 
1159 // Other sequence operations.
1160 struct SizeInst : public MemOIRInst {
1161 public:
1162  llvm::Value &getSize() const;
1163 
1164  llvm::Value &getCollection() const;
1165  llvm::Use &getCollectionAsUse() const;
1166 
1167  static bool classof(const MemOIRInst *I) {
1168  return (I->getKind() == MemOIR_Func::SIZE);
1169  };
1170 
1171  std::string toString(std::string indent = "") const override;
1172 
1173 protected:
1174  SizeInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
1175 
1176  friend struct MemOIRInst;
1177 };
1178 
1179 struct EndInst : public MemOIRInst {
1180 public:
1181  llvm::Value &getValue() const;
1182 
1183  static bool classof(const MemOIRInst *I) {
1184  return (I->getKind() == MemOIR_Func::END);
1185  };
1186 
1187  std::string toString(std::string indent = "") const override;
1188 
1189 protected:
1190  EndInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
1191 
1192  friend struct MemOIRInst;
1193 };
1194 
1195 // Assoc operations.
1196 struct AssocHasInst : public AccessInst {
1197 public:
1198  llvm::Value &getObjectOperand() const override;
1199  llvm::Use &getObjectOperandAsUse() const override;
1200 
1201  llvm::Value &getKeyOperand() const;
1202  llvm::Use &getKeyOperandAsUse() const;
1203 
1204  static bool classof(const MemOIRInst *I) {
1205  return (I->getKind() == MemOIR_Func::ASSOC_HAS);
1206  };
1207 
1208  std::string toString(std::string indent = "") const override;
1209 
1210 protected:
1211  AssocHasInst(llvm::CallInst &call_inst) : AccessInst(call_inst) {}
1212 
1213  friend struct MemOIRInst;
1214 };
1215 
1216 struct AssocInsertInst : public InsertInst {
1217 public:
1218  llvm::Value &getBaseCollection() const override;
1219  llvm::Use &getBaseCollectionAsUse() const override;
1220 
1221  llvm::Value &getInsertionPoint() const override;
1222  llvm::Use &getInsertionPointAsUse() const override;
1223 
1224  static bool classof(const MemOIRInst *I) {
1225  return (I->getKind() == MemOIR_Func::ASSOC_INSERT);
1226  };
1227 
1228  std::string toString(std::string indent = "") const override;
1229 
1230 protected:
1231  AssocInsertInst(llvm::CallInst &call_inst) : InsertInst(call_inst) {}
1232 
1233  friend struct MemOIRInst;
1234 };
1235 
1236 struct AssocRemoveInst : public RemoveInst {
1237 public:
1238  llvm::Value &getBaseCollection() const override;
1239  llvm::Use &getBaseCollectionAsUse() const override;
1240 
1241  llvm::Value &getKey() const;
1242  llvm::Use &getKeyAsUse() const;
1243 
1244  static bool classof(const MemOIRInst *I) {
1245  return (I->getKind() == MemOIR_Func::ASSOC_REMOVE);
1246  };
1247 
1248  std::string toString(std::string indent = "") const override;
1249 
1250 protected:
1251  AssocRemoveInst(llvm::CallInst &call_inst) : RemoveInst(call_inst) {}
1252 
1253  friend struct MemOIRInst;
1254 };
1255 
1256 struct AssocKeysInst : public MemOIRInst {
1257 public:
1258  llvm::Value &getKeys() const;
1259 
1260  llvm::Value &getCollection() const;
1261  llvm::Use &getCollectionAsUse() const;
1262 
1263  static bool classof(const MemOIRInst *I) {
1264  return (I->getKind() == MemOIR_Func::ASSOC_KEYS);
1265  };
1266 
1267  std::string toString(std::string indent = "") const override;
1268 
1269 protected:
1270  AssocKeysInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
1271 
1272  friend struct MemOIRInst;
1273 };
1274 
1275 // Fold operations.
1276 struct FoldInst : public MemOIRInst {
1277 public:
1278  llvm::Value &getResult() const;
1279 
1280  llvm::Value &getInitial() const;
1281  llvm::Use &getInitialAsUse() const;
1282 
1283  llvm::Value &getCollection() const;
1284  llvm::Use &getCollectionAsUse() const;
1285 
1286  llvm::Function &getFunction() const;
1287  llvm::Value &getFunctionOperand() const;
1288  llvm::Use &getFunctionOperandAsUse() const;
1289 
1290  unsigned getNumberOfClosed() const;
1291  llvm::Value &getClosed(unsigned index) const;
1292  llvm::Use &getClosedAsUse(unsigned index) const;
1293 
1294  std::string toString(std::string indent = "") const override;
1295 
1296  static bool classof(const MemOIRInst *I) {
1297  return
1298 #define HANDLE_FOLD_INST(ENUM, FUNC, CLASS) \
1299  (I->getKind() == MemOIR_Func::ENUM) ||
1300 #include "memoir/ir/Instructions.def"
1301  false;
1302  };
1303 
1304 protected:
1305  FoldInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
1306 
1307  friend struct MemOIRInst;
1308 };
1309 
1310 // SSA/readonce operations.
1311 struct UsePHIInst : public MemOIRInst {
1312 public:
1313  llvm::Value &getResultCollection() const;
1314 
1315  llvm::Value &getUsedCollection() const;
1316  llvm::Use &getUsedCollectionAsUse() const;
1317 
1318  llvm::Instruction &getUseInst() const;
1319  void setUseInst(llvm::Instruction &I) const;
1320  void setUseInst(MemOIRInst &I) const;
1321 
1322  static bool classof(const MemOIRInst *I) {
1323  return (I->getKind() == MemOIR_Func::USE_PHI);
1324  };
1325 
1326  std::string toString(std::string indent = "") const override;
1327 
1328 protected:
1329  UsePHIInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
1330 
1331  friend struct MemOIRInst;
1332 };
1333 
1334 struct DefPHIInst : public MemOIRInst {
1335 public:
1336  llvm::Value &getResultCollection() const;
1337 
1338  llvm::Value &getDefinedCollection() const;
1339  llvm::Use &getDefinedCollectionAsUse() const;
1340 
1341  llvm::Instruction &getDefInst() const;
1342  void setDefInst(llvm::Instruction &I) const;
1343  void setDefInst(MemOIRInst &I) const;
1344 
1345  static bool classof(const MemOIRInst *I) {
1346  return (I->getKind() == MemOIR_Func::DEF_PHI);
1347  };
1348 
1349  std::string toString(std::string indent = "") const override;
1350 
1351 protected:
1352  DefPHIInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
1353 
1354  friend struct MemOIRInst;
1355 };
1356 
1357 struct ArgPHIInst : public MemOIRInst {
1358 public:
1359  llvm::Value &getResultCollection() const;
1360 
1361  llvm::Value &getInputCollection() const;
1362  llvm::Use &getInputCollectionAsUse() const;
1363 
1364  // TODO: add methods for decoding the metadata
1365 
1366  static bool classof(const MemOIRInst *I) {
1367  return (I->getKind() == MemOIR_Func::ARG_PHI);
1368  };
1369 
1370  std::string toString(std::string indent = "") const override;
1371 
1372 protected:
1373  ArgPHIInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
1374 
1375  friend struct MemOIRInst;
1376 };
1377 
1378 struct RetPHIInst : public MemOIRInst {
1379 public:
1380  llvm::Value &getResultCollection() const;
1381 
1382  llvm::Value &getInputCollection() const;
1383  llvm::Use &getInputCollectionAsUse() const;
1384 
1385  // TODO: add methods for decoding the metadata.
1386 
1387  static bool classof(const MemOIRInst *I) {
1388  return (I->getKind() == MemOIR_Func::RET_PHI);
1389  };
1390 
1391  std::string toString(std::string indent = "") const override;
1392 
1393 protected:
1394  RetPHIInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
1395 
1396  friend struct MemOIRInst;
1397 };
1398 
1399 // Deletion operations
1400 struct DeleteStructInst : public MemOIRInst {
1401 public:
1402  llvm::Value &getDeletedStruct() const;
1403  llvm::Use &getDeletedStructAsUse() const;
1404 
1405  static bool classof(const MemOIRInst *I) {
1406  return (I->getKind() == MemOIR_Func::DELETE_STRUCT);
1407  };
1408 
1409  std::string toString(std::string indent = "") const override;
1410 
1411 protected:
1412  DeleteStructInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
1413 
1414  friend struct MemOIRInst;
1415 };
1416 
1418 public:
1419  llvm::Value &getDeletedCollection() const;
1420  llvm::Use &getDeletedCollectionAsUse() const;
1421 
1422  static bool classof(const MemOIRInst *I) {
1423  return (I->getKind() == MemOIR_Func::DELETE_COLLECTION);
1424  };
1425 
1426  std::string toString(std::string indent = "") const override;
1427 
1428 protected:
1429  DeleteCollectionInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
1430 
1431  friend struct MemOIRInst;
1432 };
1433 
1434 // Type checking
1435 struct AssertTypeInst : public MemOIRInst {
1436 public:
1437  virtual Type &getType() const = 0;
1438  virtual llvm::Value &getTypeOperand() const = 0;
1439  virtual llvm::Use &getTypeOperandAsUse() const = 0;
1440 
1441  virtual llvm::Value &getObject() const = 0;
1442  virtual llvm::Use &getObjectAsUse() const = 0;
1443 
1444  static bool classof(const MemOIRInst *I) {
1445  return
1446 #define HANDLE_ASSERT_TYPE_INST(ENUM, FUNC, CLASS) \
1447  (I->getKind() == MemOIR_Func::ENUM) ||
1448 #include "memoir/ir/Instructions.def"
1449  false;
1450  }
1451 
1452 protected:
1453  AssertTypeInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
1454 
1455  friend struct MemOIRInst;
1456 };
1457 
1459 public:
1460  Type &getType() const override;
1461  llvm::Value &getTypeOperand() const override;
1462  llvm::Use &getTypeOperandAsUse() const override;
1463 
1464  llvm::Value &getStruct() const;
1465  llvm::Use &getStructAsUse() const;
1466  llvm::Value &getObject() const override;
1467  llvm::Use &getObjectAsUse() const override;
1468 
1469  static bool classof(const MemOIRInst *I) {
1470  return (I->getKind() == MemOIR_Func::ASSERT_STRUCT_TYPE);
1471  };
1472 
1473  std::string toString(std::string indent = "") const override;
1474 
1475 protected:
1476  AssertStructTypeInst(llvm::CallInst &call_inst) : AssertTypeInst(call_inst) {}
1477 
1478  friend struct MemOIRInst;
1479 };
1480 
1482 public:
1483  Type &getType() const override;
1484  llvm::Value &getTypeOperand() const override;
1485  llvm::Use &getTypeOperandAsUse() const override;
1486 
1487  llvm::Value &getCollection() const;
1488  llvm::Use &getCollectionAsUse() const;
1489  llvm::Value &getObject() const override;
1490  llvm::Use &getObjectAsUse() const override;
1491 
1492  static bool classof(const MemOIRInst *I) {
1493  return (I->getKind() == MemOIR_Func::ASSERT_COLLECTION_TYPE);
1494  };
1495 
1496  std::string toString(std::string indent = "") const override;
1497 
1498 protected:
1499  AssertCollectionTypeInst(llvm::CallInst &call_inst)
1500  : AssertTypeInst(call_inst) {}
1501 
1502  friend struct MemOIRInst;
1503 };
1504 
1505 struct ReturnTypeInst : public MemOIRInst {
1506 public:
1507  Type &getType() const;
1508  llvm::Value &getTypeOperand() const;
1509  llvm::Use &getTypeOperandAsUse() const;
1510 
1511  static bool classof(const MemOIRInst *I) {
1512  return (I->getKind() == MemOIR_Func::SET_RETURN_TYPE);
1513  };
1514 
1515  std::string toString(std::string indent = "") const override;
1516 
1517 protected:
1518  ReturnTypeInst(llvm::CallInst &call_inst) : MemOIRInst(call_inst) {}
1519 
1520  friend struct MemOIRInst;
1521 };
1522 
1523 } // namespace llvm::memoir
1524 
1525 #endif
Definition: Instructions.hpp:283
Definition: Instructions.hpp:267
Definition: Instructions.hpp:187
Definition: Instructions.hpp:1256
Definition: Instructions.hpp:139
Definition: Instructions.hpp:928
Definition: Instructions.hpp:155
Definition: Instructions.hpp:745
Definition: Instructions.hpp:1417
Definition: Instructions.hpp:634
Definition: Instructions.hpp:489
Definition: Instructions.hpp:679
Definition: Instructions.hpp:701
Definition: Instructions.hpp:171
Definition: Instructions.hpp:1400
Definition: Instructions.hpp:586
Definition: Instructions.hpp:1481
Definition: Instructions.hpp:978
Definition: Instructions.hpp:1086
Definition: Instructions.hpp:655
Definition: Instructions.hpp:1019
Definition: Instructions.hpp:1236
Definition: Instructions.hpp:1435
Definition: Types.hpp:213
Definition: Instructions.hpp:1311
Definition: Instructions.hpp:405
Definition: Instructions.hpp:1334
Definition: Instructions.hpp:450
Definition: Instructions.hpp:73
Definition: Instructions.hpp:884
Definition: Instructions.hpp:235
Definition: Instructions.hpp:1276
Definition: Instructions.hpp:315
Definition: Instructions.hpp:219
Definition: Instructions.hpp:470
Definition: Instructions.hpp:1139
Definition: Instructions.hpp:906
Definition: Instructions.hpp:559
Definition: Instructions.hpp:361
Definition: Instructions.hpp:1458
Definition: Instructions.hpp:427
Definition: Instructions.hpp:299
Definition: Instructions.hpp:862
Definition: Instructions.hpp:996
Definition: Instructions.hpp:1196
Definition: Instructions.hpp:334
Definition: Instructions.hpp:1216
Definition: Instructions.hpp:1053
Definition: Instructions.hpp:532
Definition: Instructions.hpp:511
Definition: Instructions.hpp:107
Definition: Instructions.hpp:91
Definition: Instructions.hpp:1179
Definition: Instructions.hpp:380
Definition: Instructions.hpp:838
Definition: Liveness.hpp:17
Definition: Instructions.hpp:955
Definition: Instructions.hpp:1119
Definition: Instructions.hpp:31
Definition: Instructions.hpp:793
Definition: Instructions.hpp:1357
Definition: Types.hpp:250
Definition: Instructions.hpp:817
Definition: Instructions.hpp:123
Definition: Types.hpp:51
Definition: Instructions.hpp:251
Definition: Instructions.hpp:1160
Definition: Instructions.hpp:612
Definition: Instructions.hpp:203
Definition: Instructions.hpp:1378
Definition: Instructions.hpp:1505
Definition: Instructions.hpp:723
Definition: Instructions.hpp:769