1 #ifndef MEMOIR_INSTRUCTIONS_H
2 #define MEMOIR_INSTRUCTIONS_H
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"
12 #include "memoir/support/DataTypes.hpp"
14 #include "memoir/utility/FunctionNames.hpp"
16 #include "memoir/ir/Keywords.hpp"
17 #include "memoir/ir/Types.hpp"
26 namespace llvm::memoir {
28 struct CollectionType;
35 static void invalidate();
37 llvm::Function &getCalledFunction()
const;
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;
45 MemOIR_Func getKind()
const;
47 bool has_keywords()
const;
49 template <
typename KeywordTy>
50 std::optional<KeywordTy> get_keyword()
const;
52 llvm::iterator_range<keyword_iterator> keywords()
const;
56 explicit operator llvm::Value *() {
57 return &this->getCallInst();
59 explicit operator llvm::Value &() {
60 return this->getCallInst();
62 explicit operator llvm::Instruction *() {
63 return &this->getCallInst();
65 explicit operator llvm::Instruction &() {
66 return this->getCallInst();
69 friend std::ostream &operator<<(std::ostream &os,
const MemOIRInst &I);
70 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
72 virtual std::string toString()
const = 0;
77 llvm::CallInst &call_inst;
79 static Map<llvm::Instruction *, MemOIRInst *> *llvm_to_memoir;
81 MemOIRInst(llvm::CallInst &call_inst) : call_inst(call_inst) {}
87 virtual Type &getType()
const = 0;
91 #define HANDLE_TYPE_INST(ENUM, FUNC, CLASS) \
92 (I->getKind() == MemOIR_Func::ENUM) ||
93 #include "memoir/ir/Instructions.def"
105 Type &getType()
const override;
108 return (I->getKind() == MemOIR_Func::UINT64_TYPE);
111 std::string toString()
const override;
121 Type &getType()
const override;
124 return (I->getKind() == MemOIR_Func::UINT32_TYPE);
127 std::string toString()
const override;
137 Type &getType()
const override;
140 return (I->getKind() == MemOIR_Func::UINT16_TYPE);
143 std::string toString()
const override;
153 Type &getType()
const override;
156 return (I->getKind() == MemOIR_Func::UINT8_TYPE);
159 std::string toString()
const override;
169 Type &getType()
const override;
172 return (I->getKind() == MemOIR_Func::UINT2_TYPE);
175 std::string toString()
const override;
185 Type &getType()
const override;
188 return (I->getKind() == MemOIR_Func::INT64_TYPE);
191 std::string toString()
const override;
201 Type &getType()
const override;
204 return (I->getKind() == MemOIR_Func::INT32_TYPE);
207 std::string toString()
const override;
217 Type &getType()
const override;
220 return (I->getKind() == MemOIR_Func::INT16_TYPE);
223 std::string toString()
const override;
233 Type &getType()
const override;
236 return (I->getKind() == MemOIR_Func::INT8_TYPE);
239 std::string toString()
const override;
249 Type &getType()
const override;
252 return (I->getKind() == MemOIR_Func::INT2_TYPE);
255 std::string toString()
const override;
265 Type &getType()
const override;
268 return (I->getKind() == MemOIR_Func::BOOL_TYPE);
271 std::string toString()
const override;
281 Type &getType()
const override;
284 return (I->getKind() == MemOIR_Func::FLOAT_TYPE);
287 std::string toString()
const override;
297 Type &getType()
const override;
300 return (I->getKind() == MemOIR_Func::DOUBLE_TYPE);
303 std::string toString()
const override;
313 Type &getType()
const override;
316 return (I->getKind() == MemOIR_Func::POINTER_TYPE);
319 std::string toString()
const override;
329 Type &getType()
const override;
332 return (I->getKind() == MemOIR_Func::VOID_TYPE);
335 std::string toString()
const override;
345 Type &getType()
const override;
346 Type &getReferencedType()
const;
347 llvm::Value &getReferencedTypeOperand()
const;
348 llvm::Use &getReferencedTypeOperandAsUse()
const;
351 return (I->getKind() == MemOIR_Func::REFERENCE_TYPE);
354 std::string toString()
const override;
363 struct DefineTypeInst :
public TypeInst {
365 Type &getType()
const override;
367 std::string getName()
const;
368 llvm::Value &getNameOperand()
const;
369 llvm::Use &getNameOperandAsUse()
const;
371 llvm::Value &getTypeOperand()
const;
372 llvm::Use &getTypeOperandAsUse()
const;
375 return (I->getKind() == MemOIR_Func::DEFINE_TYPE);
378 std::string toString()
const override;
381 DefineTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
383 friend struct MemOIRInst;
386 struct LookupTypeInst :
public TypeInst {
388 Type &getType()
const override;
390 std::string getName()
const;
391 llvm::Value &getNameOperand()
const;
392 llvm::Use &getNameOperandAsUse()
const;
394 static bool classof(
const MemOIRInst *I) {
395 return (I->getKind() == MemOIR_Func::LOOKUP_TYPE);
398 std::string toString()
const override;
401 LookupTypeInst(llvm::CallInst &call_inst) : TypeInst(call_inst) {}
403 friend struct MemOIRInst;
409 Type &getType()
const override;
411 unsigned getNumberOfFields()
const;
412 llvm::Value &getNumberOfFieldsOperand()
const;
413 llvm::Use &getNumberOfFieldsOperandAsUse()
const;
415 Type &getFieldType(
unsigned field_index)
const;
416 llvm::Value &getFieldTypeOperand(
unsigned field_index)
const;
417 llvm::Use &getFieldTypeOperandAsUse(
unsigned field_index)
const;
420 return (I->getKind() == MemOIR_Func::TUPLE_TYPE);
423 std::string toString()
const override;
433 Type &getType()
const override;
435 Type &getElementType()
const;
436 llvm::Value &getElementTypeOperand()
const;
437 llvm::Use &getElementTypeOperandAsUse()
const;
439 size_t getLength()
const;
440 llvm::Value &getLengthOperand()
const;
441 llvm::Use &getLengthOperandAsUse()
const;
444 return (I->getKind() == MemOIR_Func::ARRAY_TYPE);
447 std::string toString()
const override;
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;
466 return (I->getKind() == MemOIR_Func::ASSOC_ARRAY_TYPE);
469 std::string toString()
const override;
480 Type &getType()
const override;
481 Type &getElementType()
const;
482 llvm::Value &getElementOperand()
const;
483 llvm::Use &getElementOperandAsUse()
const;
486 return (I->getKind() == MemOIR_Func::SEQUENCE_TYPE);
489 std::string toString()
const override;
500 llvm::Value &getAllocation()
const;
502 Type &getType()
const;
503 llvm::Value &getTypeOperand()
const;
504 llvm::Use &getTypeOperandAsUse()
const;
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();
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;
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();
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;
528 #define HANDLE_ALLOC_INST(ENUM, FUNC, CLASS) \
529 (I->getKind() == MemOIR_Func::ENUM) ||
530 #include "memoir/ir/Instructions.def"
534 std::string toString()
const override;
545 Type &getObjectType()
const;
546 Type &getElementType()
const;
548 virtual llvm::Value &getObject()
const = 0;
549 virtual llvm::Use &getObjectAsUse()
const = 0;
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();
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;
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();
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;
577 Option<size_t>
match_offsets(llvm::ArrayRef<unsigned> offsets)
const;
581 #define HANDLE_ACCESS_INST(ENUM, FUNC, CLASS) \
582 (I->getKind() == MemOIR_Func::ENUM) ||
583 #include
"memoir/ir/Instructions.def"
595 llvm::Value &getValueRead()
const;
597 llvm::Value &getObject()
const override;
598 llvm::Use &getObjectAsUse()
const override;
602 #define HANDLE_READ_INST(ENUM, FUNC, CLASS) \
603 (I->getKind() == MemOIR_Func::ENUM) ||
604 #include "memoir/ir/Instructions.def"
608 std::string toString()
const override;
621 llvm::Value &getNestedObject()
const;
623 llvm::Value &getObject()
const override;
624 llvm::Use &getObjectAsUse()
const override;
627 return I->getKind() == MemOIR_Func::GET;
630 std::string toString()
const override;
639 llvm::Value &getResult()
const;
641 llvm::Value &getObject()
const override;
642 llvm::Use &getObjectAsUse()
const override;
645 return I->getKind() == MemOIR_Func::COPY;
648 std::string toString()
const override;
658 llvm::Value &getSize()
const;
660 llvm::Value &getObject()
const override;
661 llvm::Use &getObjectAsUse()
const override;
664 return I->getKind() == MemOIR_Func::SIZE;
667 std::string toString()
const override;
678 llvm::Value &getResult()
const;
682 #define HANDLE_UPDATE_INST(ENUM, FUNC, CLASS) \
683 (I->getKind() == MemOIR_Func::ENUM) ||
684 #include "memoir/ir/Instructions.def"
696 llvm::Value &getResult()
const;
698 llvm::Value &getValueWritten()
const;
699 llvm::Use &getValueWrittenAsUse()
const;
701 llvm::Value &getObject()
const override;
702 llvm::Use &getObjectAsUse()
const override;
706 #define HANDLE_WRITE_INST(ENUM, FUNC, CLASS) \
707 (I->getKind() == MemOIR_Func::ENUM) ||
708 #include "memoir/ir/Instructions.def"
712 std::string toString()
const override;
722 llvm::Value &getObject()
const override;
723 llvm::Use &getObjectAsUse()
const override;
726 return I->getKind() == MemOIR_Func::INSERT;
729 std::string toString()
const override;
739 llvm::Value &getObject()
const override;
740 llvm::Use &getObjectAsUse()
const override;
743 return I->getKind() == MemOIR_Func::REMOVE;
746 std::string toString()
const override;
756 llvm::Value &getObject()
const override;
757 llvm::Use &getObjectAsUse()
const override;
760 return (I->getKind() == MemOIR_Func::CLEAR);
763 std::string toString()
const override;
775 llvm::Value &getResult()
const;
777 llvm::Value &getObject()
const override;
778 llvm::Use &getObjectAsUse()
const override;
781 return (I->getKind() == MemOIR_Func::HAS);
784 std::string toString()
const override;
794 llvm::Value &getResult()
const;
796 llvm::Value &getObject()
const override;
797 llvm::Use &getObjectAsUse()
const override;
800 return (I->getKind() == MemOIR_Func::KEYS);
803 std::string toString()
const override;
821 llvm::Value &getResult()
const;
823 bool isReverse()
const;
825 llvm::Value &getInitial()
const;
826 llvm::Use &getInitialAsUse()
const;
828 llvm::Value &getObject()
const override;
829 llvm::Use &getObjectAsUse()
const override;
831 llvm::Function &getBody()
const;
832 llvm::Value &getBodyOperand()
const;
833 llvm::Use &getBodyOperandAsUse()
const;
835 std::optional<ClosedKeyword> getClosed()
const;
837 using iterator = ClosedKeyword::iterator;
838 llvm::iterator_range<iterator> closed();
839 iterator closed_begin();
840 iterator closed_end();
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();
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;
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;
892 std::string toString()
const override;
896 #define HANDLE_FOLD_INST(ENUM, FUNC, CLASS) \
897 (I->getKind() == MemOIR_Func::ENUM) ||
898 #include "memoir/ir/Instructions.def"
911 llvm::Value &getResult()
const;
913 llvm::Value &getUsed()
const;
914 llvm::Use &getUsedAsUse()
const;
917 return (I->getKind() == MemOIR_Func::USE_PHI);
920 std::string toString()
const override;
930 llvm::Value &getValue()
const;
933 return (I->getKind() == MemOIR_Func::END);
936 std::string toString()
const override;
946 llvm::Value &getResult()
const;
948 llvm::Value &getInput()
const;
949 llvm::Use &getInputAsUse()
const;
956 llvm::Value &getCalledOperand()
const;
957 llvm::Use &getCalledOperandAsUse()
const;
962 return (I->getKind() == MemOIR_Func::RET_PHI);
965 std::string toString()
const override;
976 llvm::Value &getObject()
const;
977 llvm::Use &getObjectAsUse()
const;
980 return (I->getKind() == MemOIR_Func::DELETE);
983 std::string toString()
const override;
994 Type &getType()
const;
995 llvm::Value &getTypeOperand()
const;
996 llvm::Use &getTypeOperandAsUse()
const;
998 llvm::Value &getObject()
const;
999 llvm::Use &getObjectAsUse()
const;
1002 return (I->getKind() == MemOIR_Func::ASSERT_TYPE);
1005 std::string toString()
const override;
1015 Type &getType()
const;
1016 llvm::Value &getTypeOperand()
const;
1017 llvm::Use &getTypeOperandAsUse()
const;
1020 return (I->getKind() == MemOIR_Func::SET_RETURN_TYPE);
1023 std::string toString()
const override;
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: 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