6#ifndef JLM_LLVM_IR_OPERATORS_OPERATORS_HPP
7#define JLM_LLVM_IR_OPERATORS_OPERATORS_HPP
20#include <llvm/ADT/APFloat.h>
21#include <llvm/IR/InstrTypes.h>
41 const std::shared_ptr<const
jlm::rvsdg::
Type> & type)
55 operator==(
const Operation & other)
const noexcept override;
60 [[nodiscard]] std::unique_ptr<Operation>
61 copy()
const override;
63 const std::shared_ptr<const rvsdg::Type> &
76 static std::unique_ptr<llvm::ThreeAddressCode>
78 const std::vector<std::pair<const Variable *, ControlFlowGraphNode *>> &
arguments,
79 std::shared_ptr<const jlm::rvsdg::Type> type)
81 std::vector<ControlFlowGraphNode *> basicBlocks;
82 std::vector<const Variable *> operands;
85 basicBlocks.push_back(
argument.second);
89 auto phi = std::make_unique<SsaPhiOperation>(std::move(basicBlocks), std::move(type));
111 operator==(
const Operation & other)
const noexcept override;
113 [[nodiscard]] std::string
116 [[nodiscard]] std::unique_ptr<Operation>
117 copy()
const override;
119 static std::unique_ptr<llvm::ThreeAddressCode>
123 throw util::Error(
"LHS and RHS of assignment must have same type.");
125 auto operation = std::make_unique<AssignmentOperation>(rhs->
Type());
140 operator==(
const Operation & other)
const noexcept override;
145 [[nodiscard]] std::unique_ptr<Operation>
146 copy()
const override;
154 [[nodiscard]]
const std::shared_ptr<const jlm::rvsdg::Type> &
160 static std::unique_ptr<llvm::ThreeAddressCode>
163 auto op = std::make_unique<SelectOperation>(t->
Type());
182 operator==(
const Operation & other)
const noexcept override;
184 [[nodiscard]] std::string
187 [[nodiscard]] std::unique_ptr<Operation>
188 copy()
const override;
190 [[nodiscard]]
const rvsdg::Type &
196 [[nodiscard]]
const std::shared_ptr<const rvsdg::Type> &
208 static std::unique_ptr<llvm::ThreeAddressCode>
211 if (is<FixedVectorType>(p->
type()) && is<FixedVectorType>(t->
type()))
212 return createVectorSelectTac<FixedVectorType>(p, t, f);
214 if (is<ScalableVectorType>(p->
type()) && is<ScalableVectorType>(t->
type()))
215 return createVectorSelectTac<ScalableVectorType>(p, t, f);
217 throw util::Error(
"Expected vector types as operands.");
222 static std::unique_ptr<ThreeAddressCode>
225 auto fvt =
static_cast<const T *
>(&t->
type());
227 auto vt = T::Create(fvt->Type(), fvt->size());
243 operator==(
const Operation & other)
const noexcept override;
245 [[nodiscard]] std::string
248 [[nodiscard]] std::unique_ptr<Operation>
249 copy()
const override;
254 return std::static_pointer_cast<const rvsdg::ControlType>(
argument(0))->nalternatives();
257 static std::unique_ptr<llvm::ThreeAddressCode>
279 operator==(
const Operation & other)
const noexcept override;
281 [[nodiscard]] std::string
284 [[nodiscard]] std::unique_ptr<Operation>
285 copy()
const override;
287 static std::unique_ptr<ThreeAddressCode>
316 operator==(
const Operation & other)
const noexcept override;
318 [[nodiscard]] std::string
321 [[nodiscard]] std::unique_ptr<Operation>
322 copy()
const override;
327 return std::static_pointer_cast<const ArrayType>(
result(0))->nelements();
330 [[nodiscard]] std::shared_ptr<const ArrayType>
334 return std::static_pointer_cast<const ArrayType>(
result(0));
337 static std::unique_ptr<ThreeAddressCode>
338 create(
const std::vector<const Variable *> & elements)
340 if (elements.size() == 0)
341 throw util::Error(
"expected at least one element.");
343 auto vt = elements[0]->Type();
347 auto op = std::make_unique<ConstantDataArrayOperation>(std::move(
vt), elements.size());
352 Create(
const std::vector<rvsdg::Output *> & elements)
354 if (elements.empty())
355 throw util::Error(
"Expected at least one element.");
357 auto valueType = elements[0]->Type();
365 std::move(valueType),
400[[nodiscard]] ::llvm::CmpInst::Predicate
407[[nodiscard]] std::string_view
421 operator==(
const Operation & other)
const noexcept override;
423 [[nodiscard]] std::string
426 [[nodiscard]] std::unique_ptr<Operation>
427 copy()
const override;
431 const noexcept override;
445 static std::unique_ptr<llvm::ThreeAddressCode>
448 auto pt = std::dynamic_pointer_cast<const PointerType>(op1->
Type());
452 auto op = std::make_unique<PtrCmpOperation>(std::move(pt), predicateKind);
460 { &operand1, &operand2 },
478 static std::optional<std::vector<rvsdg::Output *>>
481 const std::vector<rvsdg::Output *> & operands);
499 static std::optional<std::vector<rvsdg::Output *>>
502 const std::vector<rvsdg::Output *> & operands);
526 operator==(
const Operation & other)
const noexcept override;
528 [[nodiscard]] std::string
531 [[nodiscard]] std::unique_ptr<Operation>
532 copy()
const override;
534 inline const ::llvm::APFloat &
543 return std::static_pointer_cast<const FloatingPointType>(
result(0))->size();
546 [[nodiscard]]
static std::unique_ptr<ConstantFP>
547 create(const ::llvm::APFloat &
constant,
const std::shared_ptr<const jlm::rvsdg::Type> & type)
549 auto ft = std::dynamic_pointer_cast<const FloatingPointType>(type);
551 throw util::Error(
"expected floating point type.");
553 return std::make_unique<ConstantFP>(std::move(ft),
constant);
556 [[nodiscard]]
static std::unique_ptr<llvm::ThreeAddressCode>
557 createTac(const ::llvm::APFloat &
constant,
const std::shared_ptr<const jlm::rvsdg::Type> & type)
571 [[nodiscard]] static ::llvm::APFloat
577 return ::llvm::APFloat::getZero(::llvm::APFloat::IEEEhalf());
579 return ::llvm::APFloat::getZero(::llvm::APFloat::IEEEsingle());
581 return ::llvm::APFloat::getZero(::llvm::APFloat::IEEEdouble());
583 return ::llvm::APFloat::getZero(::llvm::APFloat::x87DoubleExtended());
585 return ::llvm::APFloat::getZero(::llvm::APFloat::IEEEquad());
637 operator==(
const Operation & other)
const noexcept override;
639 [[nodiscard]] std::string
642 [[nodiscard]] std::unique_ptr<Operation>
643 copy()
const override;
647 const noexcept override;
664 return std::static_pointer_cast<const FloatingPointType>(
argument(0))->size();
677 static std::optional<std::vector<rvsdg::Output *>>
680 static std::unique_ptr<llvm::ThreeAddressCode>
683 auto ft = std::dynamic_pointer_cast<const FloatingPointType>(op1->
Type());
685 throw util::Error(
"expected floating point type.");
687 auto op = std::make_unique<FCmpOperation>(
cmp, std::move(ft));
717 operator==(
const Operation & other)
const noexcept override;
719 [[nodiscard]] std::string
722 [[nodiscard]] std::unique_ptr<Operation>
723 copy()
const override;
737 static std::unique_ptr<llvm::ThreeAddressCode>
738 Create(std::shared_ptr<const jlm::rvsdg::Type> type)
740 auto operation = std::make_unique<UndefValueOperation>(std::move(type));
744 static std::unique_ptr<llvm::ThreeAddressCode>
745 Create(std::shared_ptr<const jlm::rvsdg::Type> type,
const std::string & name)
747 auto operation = std::make_unique<UndefValueOperation>(std::move(type));
751 static std::unique_ptr<llvm::ThreeAddressCode>
754 auto & type =
result->Type();
756 std::vector<std::unique_ptr<ThreeAddressCodeVariable>> results;
757 results.push_back(std::move(
result));
759 auto operation = std::make_unique<UndefValueOperation>(type);
788 operator==(
const Operation & other)
const noexcept override;
793 [[nodiscard]] std::unique_ptr<Operation>
794 copy()
const override;
802 static std::unique_ptr<llvm::ThreeAddressCode>
803 Create(
const std::shared_ptr<const jlm::rvsdg::Type> & type)
807 auto operation = std::make_unique<PoisonValueOperation>(std::move(valueType));
820 static std::shared_ptr<const jlm::rvsdg::Type>
845 throw std::runtime_error(
"FreezeOperation given non-value type");
849 operator==(
const Operation & other)
const noexcept override;
854 [[nodiscard]] std::unique_ptr<Operation>
855 copy()
const override;
863 static std::unique_ptr<llvm::ThreeAddressCode>
866 auto operation = std::make_unique<FreezeOperation>(operand.
Type());
906 operator==(
const Operation & other)
const noexcept override;
908 [[nodiscard]] std::string
911 [[nodiscard]] std::unique_ptr<Operation>
912 copy()
const override;
916 const noexcept override;
933 return std::static_pointer_cast<const FloatingPointType>(
result(0))->size();
936 static std::unique_ptr<llvm::ThreeAddressCode>
939 auto ft = std::dynamic_pointer_cast<const FloatingPointType>(op1->
Type());
941 throw util::Error(
"expected floating point type.");
943 auto op = std::make_unique<FBinaryOperation>(
fpop, ft);
957 static std::optional<std::vector<rvsdg::Output *>>
973 explicit FNegOperation(
const std::shared_ptr<const FloatingPointType> & fpt)
978 operator==(
const Operation & other)
const noexcept override;
980 [[nodiscard]] std::string
983 [[nodiscard]] std::unique_ptr<Operation>
984 copy()
const override;
989 return std::static_pointer_cast<const FloatingPointType>(
argument(0))->size();
992 static std::unique_ptr<llvm::ThreeAddressCode>
995 auto type = std::dynamic_pointer_cast<const FloatingPointType>(operand->
Type());
997 throw util::Error(
"expected floating point type.");
999 auto op = std::make_unique<FNegOperation>(std::move(type));
1022 operator==(
const Operation & other)
const noexcept override;
1024 [[nodiscard]] std::string
1027 [[nodiscard]] std::unique_ptr<Operation>
1028 copy()
const override;
1030 static std::unique_ptr<llvm::ThreeAddressCode>
1033 std::vector<std::shared_ptr<const jlm::rvsdg::Type>> operands;
1035 operands.push_back(
argument->Type());
1037 auto op = std::make_unique<VariadicArgumentListOperation>(std::move(operands));
1044 std::vector<std::shared_ptr<const rvsdg::Type>> operandTypes;
1045 operandTypes.reserve(operands.size());
1046 for (
auto & operand : operands)
1047 operandTypes.emplace_back(operand->Type());
1049 return operands.empty()
1067 operator==(
const Operation & other)
const noexcept override;
1069 [[nodiscard]] std::string
1072 [[nodiscard]] std::unique_ptr<Operation>
1073 copy()
const override;
1078 return *std::static_pointer_cast<const StructType>(
result(0));
1081 static std::unique_ptr<ThreeAddressCode>
1083 const std::vector<const Variable *> & elements,
1084 const std::shared_ptr<const rvsdg::Type> &
type)
1088 auto op = std::make_unique<ConstantStructOperation>(std::move(structType));
1095 const std::vector<rvsdg::Output *> & operands,
1096 std::shared_ptr<const rvsdg::Type> resultType)
1103 static std::vector<std::shared_ptr<const rvsdg::Type>>
1106 std::vector<std::shared_ptr<const rvsdg::Type>> types;
1113 static std::shared_ptr<const StructType>
1116 if (
auto structType = std::dynamic_pointer_cast<const StructType>(
type))
1138 operator==(
const Operation & other)
const noexcept override;
1140 [[nodiscard]] std::string
1143 [[nodiscard]] std::unique_ptr<Operation>
1144 copy()
const override;
1149 return std::static_pointer_cast<const ArrayType>(
result(0))->nelements();
1152 [[nodiscard]] std::shared_ptr<const ArrayType>
1156 return std::static_pointer_cast<const ArrayType>(
result(0));
1159 static std::unique_ptr<llvm::ThreeAddressCode>
1160 create(
const std::vector<const Variable *> & elements)
1162 if (elements.size() == 0)
1163 throw util::Error(
"expected at least one element.\n");
1165 auto vt = elements[0]->Type();
1169 auto op = std::make_unique<ConstantArrayOperation>(
vt, elements.size());
1174 Create(
const std::vector<rvsdg::Output *> & operands)
1176 if (operands.empty())
1177 throw util::Error(
"Expected at least one element.\n");
1179 auto valueType = operands[0]->Type();
1198 auto st =
dynamic_cast<const StructType *
>(type.get());
1199 auto at =
dynamic_cast<const ArrayType *
>(type.get());
1200 auto vt =
dynamic_cast<const VectorType *
>(type.get());
1201 if (!st && !at && !
vt)
1202 throw util::Error(
"expected array, struct, or vector type.\n");
1206 operator==(
const Operation & other)
const noexcept override;
1208 [[nodiscard]] std::string
1211 [[nodiscard]] std::unique_ptr<Operation>
1212 copy()
const override;
1214 static std::unique_ptr<llvm::ThreeAddressCode>
1215 create(std::shared_ptr<const jlm::rvsdg::Type> type)
1217 auto op = std::make_unique<ConstantAggregateZeroOperation>(std::move(type));
1240 const std::shared_ptr<const
VectorType> & vtype,
1241 const std::shared_ptr<const
jlm::rvsdg::BitType> & btype)
1246 operator==(
const Operation & other)
const noexcept override;
1248 [[nodiscard]] std::string
1251 [[nodiscard]] std::unique_ptr<Operation>
1252 copy()
const override;
1254 static inline std::unique_ptr<llvm::ThreeAddressCode>
1257 auto vt = std::dynamic_pointer_cast<const VectorType>(vector->
Type());
1261 auto bt = std::dynamic_pointer_cast<const jlm::rvsdg::BitType>(index->
Type());
1265 auto op = std::make_unique<ExtractElementOperation>(
vt, bt);
1277 const std::vector<
int> & mask)
1283 const std::shared_ptr<const ScalableVectorType> & v,
1284 const std::vector<int> & mask)
1290 operator==(
const Operation & other)
const noexcept override;
1292 [[nodiscard]] std::string
1295 [[nodiscard]] std::unique_ptr<Operation>
1296 copy()
const override;
1298 const ::llvm::ArrayRef<int>
1304 static std::unique_ptr<llvm::ThreeAddressCode>
1307 if (is<FixedVectorType>(v1->
type()) && is<FixedVectorType>(v2->
type()))
1308 return CreateShuffleVectorTac<FixedVectorType>(v1, v2, mask);
1310 if (is<ScalableVectorType>(v1->
type()) && is<ScalableVectorType>(v2->
type()))
1311 return CreateShuffleVectorTac<ScalableVectorType>(v1, v2, mask);
1313 throw util::Error(
"Expected vector types as operands.");
1317 template<
typename T>
1318 static std::unique_ptr<ThreeAddressCode>
1321 auto vt = std::static_pointer_cast<const T>(v1->
Type());
1322 auto op = std::make_unique<ShuffleVectorOperation>(
vt, mask);
1339 operator==(
const Operation & other)
const noexcept override;
1341 [[nodiscard]] std::string
1344 [[nodiscard]] std::unique_ptr<Operation>
1345 copy()
const override;
1347 static inline std::unique_ptr<llvm::ThreeAddressCode>
1349 const std::vector<const Variable *> & operands,
1350 const std::shared_ptr<const jlm::rvsdg::Type> & type)
1352 auto vt = std::dynamic_pointer_cast<const VectorType>(type);
1356 auto op = std::make_unique<ConstantVectorOperation>(
vt);
1367 const std::shared_ptr<const
VectorType> & vectype,
1368 const std::shared_ptr<const
jlm::rvsdg::Type> & vtype,
1369 const std::shared_ptr<const
jlm::rvsdg::BitType> & btype)
1372 if (vectype->type() != *vtype)
1375 auto expected = vectype->type().debug_string();
1381 operator==(
const Operation & other)
const noexcept override;
1383 [[nodiscard]] std::string
1386 [[nodiscard]] std::unique_ptr<Operation>
1387 copy()
const override;
1389 static inline std::unique_ptr<llvm::ThreeAddressCode>
1392 auto vct = std::dynamic_pointer_cast<const VectorType>(vector->
Type());
1400 auto bt = std::dynamic_pointer_cast<const jlm::rvsdg::BitType>(index->
Type());
1404 auto op = std::make_unique<InsertElementOperation>(vct,
vt, bt);
1415 const rvsdg::UnaryOperation & op,
1416 const std::shared_ptr<const
VectorType> & operand,
1425 if (operand->type() != *op.argument(0))
1427 auto received = operand->type().debug_string();
1428 auto expected = op.argument(0)->debug_string();
1432 if (
result->type() != *op.result(0))
1434 auto received =
result->type().debug_string();
1435 auto expected = op.result(0)->debug_string();
1447 op_(std::move(other.op_))
1463 op_ = std::move(other.op_);
1475 operator==(
const Operation & other)
const noexcept override;
1477 [[nodiscard]] std::string
1480 [[nodiscard]] std::unique_ptr<Operation>
1481 copy()
const override;
1483 static inline std::unique_ptr<llvm::ThreeAddressCode>
1487 const std::shared_ptr<const jlm::rvsdg::Type> & type)
1489 auto vct1 = std::dynamic_pointer_cast<const VectorType>(operand->
Type());
1490 auto vct2 = std::dynamic_pointer_cast<const VectorType>(type);
1494 auto op = std::make_unique<VectorUnaryOperation>(unop, vct1, vct2);
1499 std::unique_ptr<Operation>
op_;
1509 const std::shared_ptr<const
VectorType> & op1,
1510 const std::shared_ptr<const
VectorType> & op2,
1516 throw util::Error(
"expected the same vector types.");
1518 if (op1->type() != *binop.argument(0))
1520 auto received = op1->type().debug_string();
1521 auto expected = binop.argument(0)->debug_string();
1525 if (
result->type() != *binop.result(0))
1527 auto received =
result->type().debug_string();
1528 auto expected = binop.result(0)->debug_string();
1540 op_(std::move(other.op_))
1556 op_ = std::move(other.op_);
1568 operator==(
const Operation & other)
const noexcept override;
1570 [[nodiscard]] std::string
1573 [[nodiscard]] std::unique_ptr<Operation>
1574 copy()
const override;
1576 static inline std::unique_ptr<llvm::ThreeAddressCode>
1581 const std::shared_ptr<const jlm::rvsdg::Type> & type)
1583 auto vct1 = std::dynamic_pointer_cast<const VectorType>(op1->
Type());
1584 auto vct2 = std::dynamic_pointer_cast<const VectorType>(op2->
Type());
1585 auto vct3 = std::dynamic_pointer_cast<const VectorType>(type);
1586 if (!vct1 || !vct2 || !vct3)
1589 auto op = std::make_unique<VectorBinaryOperation>(binop, vct1, vct2, vct3);
1594 std::unique_ptr<Operation>
op_;
1609 operator==(
const Operation & other)
const noexcept override;
1611 [[nodiscard]] std::string
1614 [[nodiscard]] std::unique_ptr<Operation>
1615 copy()
const override;
1620 return std::static_pointer_cast<const VectorType>(
result(0))->size();
1626 return std::static_pointer_cast<const VectorType>(
result(0))->type();
1629 static std::unique_ptr<ThreeAddressCode>
1630 Create(
const std::vector<const Variable *> & elements)
1632 if (elements.empty())
1633 throw util::Error(
"Expected at least one element.");
1635 auto vt = elements[0]->Type();
1639 auto op = std::unique_ptr<ConstantDataVectorOperation>(
1662 operator==(
const Operation & other)
const noexcept override;
1664 [[nodiscard]] std::string
1667 [[nodiscard]] std::unique_ptr<Operation>
1668 copy()
const override;
1670 const rvsdg::BitType &
1673 return *std::static_pointer_cast<const rvsdg::BitType>(
argument(0));
1687 auto & size = *node.
input(0);
1696 auto & ioState = *node.
input(1);
1705 auto & address = *node.
output(0);
1714 auto & ioState = *node.
output(1);
1723 auto & memoryState = *node.
output(2);
1724 JLM_ASSERT(is<MemoryStateType>(memoryState.Type()));
1728 static std::unique_ptr<ThreeAddressCode>
1732 auto op = std::make_unique<MallocOperation>(std::move(bitType));
1744 static std::shared_ptr<const rvsdg::BitType>
1747 if (
auto bitType = std::dynamic_pointer_cast<const rvsdg::BitType>(type))
1750 throw std::runtime_error(
"Expected bits type.");
1769 operator==(
const Operation & other)
const noexcept override;
1771 [[nodiscard]] std::string
1774 [[nodiscard]] std::unique_ptr<Operation>
1775 copy()
const override;
1777 [[nodiscard]]
size_t
1792 const auto input = node.input(0);
1801 const auto input = node.input(1);
1810 const auto output = node.output(0);
1818 JLM_ASSERT(is<MemoryStateType>(output.Type()));
1821 const auto input = freeNode->input(output.index() + 1);
1822 JLM_ASSERT(is<MemoryStateType>(input->Type()));
1829 const auto freeOperation = util::assertedCast<const FreeOperation>(&node.GetOperation());
1830 if (freeOperation->numMemoryStates() == 0)
1835 const auto firstMemoryStateOutput = node.output(1);
1836 JLM_ASSERT(is<MemoryStateType>(firstMemoryStateOutput->Type()));
1840 static std::unique_ptr<ThreeAddressCode>
1844 const std::vector<const Variable *> & memoryStates)
1846 std::vector<const Variable *> operands;
1847 operands.push_back(pointer);
1848 operands.push_back(iOState);
1849 operands.insert(operands.end(), memoryStates.begin(), memoryStates.end());
1851 auto operation = std::make_unique<FreeOperation>(memoryStates.size());
1859 const std::vector<rvsdg::Output *> & memoryStates)
1861 std::vector<rvsdg::Output *> operands;
1862 operands.push_back(&pointer);
1863 operands.push_back(&iOState);
1864 operands.insert(operands.end(), memoryStates.begin(), memoryStates.end());
1869 static std::vector<rvsdg::Output *>
1873 const std::vector<rvsdg::Output *> & memoryStates)
1875 return outputs(&
createNode(pointer, IOState, memoryStates));
1879 static std::vector<std::shared_ptr<const rvsdg::Type>>
1882 std::vector<std::shared_ptr<const rvsdg::Type>> types(
1889 static std::vector<std::shared_ptr<const rvsdg::Type>>
util::HashSet< rvsdg::Output * > arguments
static std::shared_ptr< const ArrayType > Create(std::shared_ptr< const Type > type, size_t nelements)
std::unique_ptr< Operation > copy() const override
static std::unique_ptr< llvm::ThreeAddressCode > create(const Variable *rhs, const Variable *lhs)
~AssignmentOperation() noexcept override
std::string debug_string() const override
AssignmentOperation(const AssignmentOperation &)=default
AssignmentOperation(AssignmentOperation &&)=default
bool operator==(const Operation &other) const noexcept override
std::string debug_string() const override
size_t nalternatives() const noexcept
~BranchOperation() noexcept override
std::unique_ptr< Operation > copy() const override
static std::unique_ptr< llvm::ThreeAddressCode > create(size_t nalternatives, const Variable *operand)
bool operator==(const Operation &other) const noexcept override
static rvsdg::SimpleNode & createNode(rvsdg::Region ®ion, std::shared_ptr< const rvsdg::Type > type)
std::unique_ptr< Operation > copy() const override
static rvsdg::Output * Create(rvsdg::Region ®ion, const std::shared_ptr< const rvsdg::Type > &type)
static std::unique_ptr< llvm::ThreeAddressCode > create(std::shared_ptr< const jlm::rvsdg::Type > type)
~ConstantAggregateZeroOperation() noexcept override
bool operator==(const Operation &other) const noexcept override
std::string debug_string() const override
~ConstantArrayOperation() noexcept override
std::unique_ptr< Operation > copy() const override
static std::unique_ptr< llvm::ThreeAddressCode > create(const std::vector< const Variable * > &elements)
bool operator==(const Operation &other) const noexcept override
std::string debug_string() const override
static rvsdg::Output * Create(const std::vector< rvsdg::Output * > &operands)
std::shared_ptr< const ArrayType > type() const noexcept
size_t size() const noexcept
~ConstantDataArrayOperation() noexcept override
static rvsdg::Output * Create(const std::vector< rvsdg::Output * > &elements)
std::unique_ptr< Operation > copy() const override
size_t size() const noexcept
std::string debug_string() const override
static std::unique_ptr< ThreeAddressCode > create(const std::vector< const Variable * > &elements)
bool operator==(const Operation &other) const noexcept override
std::shared_ptr< const ArrayType > type() const noexcept
bool operator==(const Operation &other) const noexcept override
~ConstantDataVectorOperation() noexcept override
std::unique_ptr< Operation > copy() const override
size_t size() const noexcept
const jlm::rvsdg::Type & type() const noexcept
static std::unique_ptr< ThreeAddressCode > Create(const std::vector< const Variable * > &elements)
std::string debug_string() const override
~ConstantFP() noexcept override
static std::unique_ptr< ConstantFP > create(const ::llvm::APFloat &constant, const std::shared_ptr< const jlm::rvsdg::Type > &type)
static std::unique_ptr< llvm::ThreeAddressCode > createTac(const ::llvm::APFloat &constant, const std::shared_ptr< const jlm::rvsdg::Type > &type)
static rvsdg::Node & createNode(rvsdg::Region ®ion, fpsize size, const ::llvm::APFloat &constant)
ConstantFP(std::shared_ptr< const FloatingPointType > fpt, const ::llvm::APFloat &constant)
const fpsize & size() const noexcept
std::unique_ptr< Operation > copy() const override
::llvm::APFloat constant_
bool operator==(const Operation &other) const noexcept override
std::string debug_string() const override
const ::llvm::APFloat & constant() const noexcept
static ::llvm::APFloat getZeroRepresentation(fpsize size)
ConstantPointerNullOperation class.
std::string debug_string() const override
static rvsdg::Node & createNode(rvsdg::Region ®ion)
static std::unique_ptr< ThreeAddressCode > createTac()
bool operator==(const Operation &other) const noexcept override
~ConstantPointerNullOperation() noexcept override
std::unique_ptr< Operation > copy() const override
std::unique_ptr< Operation > copy() const override
static std::unique_ptr< ThreeAddressCode > create(const std::vector< const Variable * > &elements, const std::shared_ptr< const rvsdg::Type > &type)
static std::vector< std::shared_ptr< const rvsdg::Type > > create_srctypes(const StructType &type)
static rvsdg::Output & Create(rvsdg::Region &, const std::vector< rvsdg::Output * > &operands, std::shared_ptr< const rvsdg::Type > resultType)
static std::shared_ptr< const StructType > CheckAndExtractStructType(std::shared_ptr< const rvsdg::Type > type)
~ConstantStructOperation() noexcept override
std::string debug_string() const override
const StructType & type() const noexcept
bool operator==(const Operation &other) const noexcept override
bool operator==(const Operation &other) const noexcept override
std::unique_ptr< Operation > copy() const override
~ConstantVectorOperation() noexcept override
std::string debug_string() const override
static std::unique_ptr< llvm::ThreeAddressCode > create(const std::vector< const Variable * > &operands, const std::shared_ptr< const jlm::rvsdg::Type > &type)
std::string debug_string() const override
jlm::rvsdg::binop_reduction_path_t can_reduce_operand_pair(const jlm::rvsdg::Output *op1, const jlm::rvsdg::Output *op2) const noexcept override
const llvm::fpop & fpop() const noexcept
std::unique_ptr< Operation > copy() const override
static std::unique_ptr< llvm::ThreeAddressCode > create(const llvm::fpop &fpop, const Variable *op1, const Variable *op2)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const FBinaryOperation &operation, const std::vector< rvsdg::Output * > &operands)
const fpsize & size() const noexcept
FBinaryOperation(const llvm::fpop &op, const std::shared_ptr< const FloatingPointType > &fpt)
jlm::rvsdg::Output * reduce_operand_pair(jlm::rvsdg::binop_reduction_path_t path, jlm::rvsdg::Output *op1, jlm::rvsdg::Output *op2) const override
~FBinaryOperation() noexcept override
bool operator==(const Operation &other) const noexcept override
const fpcmp & cmp() const noexcept
jlm::rvsdg::binop_reduction_path_t can_reduce_operand_pair(const jlm::rvsdg::Output *op1, const jlm::rvsdg::Output *op2) const noexcept override
static std::unique_ptr< llvm::ThreeAddressCode > create(const fpcmp &cmp, const Variable *op1, const Variable *op2)
const fpsize & size() const noexcept
~FCmpOperation() noexcept override
FCmpOperation(const fpcmp &cmp, const std::shared_ptr< const FloatingPointType > &fpt)
std::string debug_string() const override
bool operator==(const Operation &other) const noexcept override
jlm::rvsdg::Output * reduce_operand_pair(jlm::rvsdg::binop_reduction_path_t path, jlm::rvsdg::Output *op1, jlm::rvsdg::Output *op2) const override
std::unique_ptr< Operation > copy() const override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const FCmpOperation &operation, const std::vector< rvsdg::Output * > &operands)
bool operator==(const Operation &other) const noexcept override
std::unique_ptr< Operation > copy() const override
static std::unique_ptr< llvm::ThreeAddressCode > create(const Variable *operand)
~FNegOperation() noexcept override
std::string debug_string() const override
const fpsize & size() const noexcept
FNegOperation(const std::shared_ptr< const FloatingPointType > &fpt)
static std::shared_ptr< const FixedVectorType > Create(std::shared_ptr< const rvsdg::Type > type, size_t size)
static std::shared_ptr< const FloatingPointType > Create(fpsize size)
static rvsdg::Input & getAddressInput(const rvsdg::Node &node) noexcept
static std::vector< rvsdg::Output * > Create(rvsdg::Output &pointer, rvsdg::Output &IOState, const std::vector< rvsdg::Output * > &memoryStates)
static rvsdg::Node::OutputIteratorRange memoryStateOutputs(const rvsdg::Node &node) noexcept
static rvsdg::Input & getIOStateInput(const rvsdg::Node &node) noexcept
size_t numMemoryStates() const noexcept
static rvsdg::Output & getIOStateOutput(const rvsdg::Node &node) noexcept
static rvsdg::Input & mapMemoryStateOutputToInput(rvsdg::Output &output) noexcept
bool operator==(const Operation &other) const noexcept override
static std::unique_ptr< ThreeAddressCode > Create(const Variable *pointer, const Variable *iOState, const std::vector< const Variable * > &memoryStates)
static rvsdg::SimpleNode & createNode(rvsdg::Output &pointer, rvsdg::Output &iOState, const std::vector< rvsdg::Output * > &memoryStates)
std::unique_ptr< Operation > copy() const override
static std::vector< std::shared_ptr< const rvsdg::Type > > createOperandTypes(const size_t numMemoryStates)
static std::vector< std::shared_ptr< const rvsdg::Type > > createResultTypes(const size_t numMemoryStates)
~FreeOperation() noexcept override
std::string debug_string() const override
static std::unique_ptr< llvm::ThreeAddressCode > createTac(const Variable &operand)
std::string debug_string() const override
~FreezeOperation() noexcept override
std::unique_ptr< Operation > copy() const override
static jlm::rvsdg::Node & createNode(jlm::rvsdg::Output &operand)
const jlm::rvsdg::Type & getType() const noexcept
bool operator==(const Operation &other) const noexcept override
static std::shared_ptr< const IOStateType > Create()
static std::unique_ptr< llvm::ThreeAddressCode > create(const llvm::Variable *vector, const llvm::Variable *value, const llvm::Variable *index)
bool operator==(const Operation &other) const noexcept override
std::string debug_string() const override
~InsertElementOperation() noexcept override
std::unique_ptr< Operation > copy() const override
bool operator==(const Operation &other) const noexcept override
std::unique_ptr< Operation > copy() const override
std::string debug_string() const override
~MallocOperation() noexcept override
static std::unique_ptr< ThreeAddressCode > createTac(const Variable *size, const Variable *ioState)
static rvsdg::Output & addressOutput(const rvsdg::Node &node)
const rvsdg::BitType & getSizeType() const noexcept
static rvsdg::Input & sizeInput(const rvsdg::Node &node)
static rvsdg::Output & memoryStateOutput(const rvsdg::Node &node)
static rvsdg::SimpleNode & createNode(rvsdg::Output &size, rvsdg::Output &ioState)
static std::shared_ptr< const rvsdg::BitType > checkAndExtractSizeType(const std::shared_ptr< const rvsdg::Type > &type)
static rvsdg::Input & ioStateInput(const rvsdg::Node &node)
rvsdg::FunctionType getFunctionType() const
static rvsdg::Output & ioStateOutput(const rvsdg::Node &node)
static std::shared_ptr< const MemoryStateType > Create()
static std::shared_ptr< const PointerType > Create()
PoisonValueOperation class.
bool operator==(const Operation &other) const noexcept override
PoisonValueOperation(PoisonValueOperation &&)=delete
~PoisonValueOperation() noexcept override
const jlm::rvsdg::Type & GetType() const noexcept
std::string debug_string() const override
PoisonValueOperation & operator=(const PoisonValueOperation &)=delete
static std::unique_ptr< llvm::ThreeAddressCode > Create(const std::shared_ptr< const jlm::rvsdg::Type > &type)
static jlm::rvsdg::Output * Create(rvsdg::Region *region, const std::shared_ptr< const jlm::rvsdg::Type > &type)
static std::shared_ptr< const jlm::rvsdg::Type > CheckAndConvertType(const std::shared_ptr< const jlm::rvsdg::Type > &type)
PoisonValueOperation & operator=(PoisonValueOperation &&)=delete
PoisonValueOperation(const PoisonValueOperation &)=default
std::unique_ptr< Operation > copy() const override
~PtrCmpOperation() noexcept override
static std::unique_ptr< llvm::ThreeAddressCode > create(ICmpPredicate predicateKind, const Variable *op1, const Variable *op2)
bool operator==(const Operation &other) const noexcept override
ICmpPredicate predicate() const noexcept
jlm::rvsdg::binop_reduction_path_t can_reduce_operand_pair(const jlm::rvsdg::Output *op1, const jlm::rvsdg::Output *op2) const noexcept override
std::string debug_string() const override
jlm::rvsdg::Output * reduce_operand_pair(jlm::rvsdg::binop_reduction_path_t path, jlm::rvsdg::Output *op1, jlm::rvsdg::Output *op2) const override
static rvsdg::SimpleNode & createNode(const ICmpPredicate kind, rvsdg::Output &operand1, rvsdg::Output &operand2)
static std::optional< std::vector< rvsdg::Output * > > normalizeIdenticalOperands(const PtrCmpOperation &ptrCmpOperation, const std::vector< rvsdg::Output * > &operands)
std::unique_ptr< Operation > copy() const override
static std::optional< std::vector< rvsdg::Output * > > normalizeNullPointerComparison(const PtrCmpOperation &ptrCmpOperation, const std::vector< rvsdg::Output * > &operands)
const std::shared_ptr< const jlm::rvsdg::Type > & Type() const noexcept
bool operator==(const Operation &other) const noexcept override
static std::unique_ptr< llvm::ThreeAddressCode > create(const llvm::Variable *p, const llvm::Variable *t, const llvm::Variable *f)
const jlm::rvsdg::Type & type() const noexcept
std::string debug_string() const override
std::unique_ptr< Operation > copy() const override
~SelectOperation() noexcept override
std::string debug_string() const override
static std::unique_ptr< ThreeAddressCode > CreateShuffleVectorTac(const Variable *v1, const Variable *v2, const std::vector< int > &mask)
std::unique_ptr< Operation > copy() const override
ShuffleVectorOperation(const std::shared_ptr< const ScalableVectorType > &v, const std::vector< int > &mask)
static std::unique_ptr< llvm::ThreeAddressCode > create(const Variable *v1, const Variable *v2, const std::vector< int > &mask)
const ::llvm::ArrayRef< int > Mask() const
bool operator==(const Operation &other) const noexcept override
~ShuffleVectorOperation() noexcept override
SsaPhiOperation & operator=(SsaPhiOperation &&)=delete
SsaPhiOperation & operator=(const SsaPhiOperation &)=delete
SsaPhiOperation(const SsaPhiOperation &)=default
ControlFlowGraphNode * GetIncomingNode(size_t n) const noexcept
static std::unique_ptr< llvm::ThreeAddressCode > create(const std::vector< std::pair< const Variable *, ControlFlowGraphNode * > > &arguments, std::shared_ptr< const jlm::rvsdg::Type > type)
std::string debug_string() const override
bool operator==(const Operation &other) const noexcept override
std::unique_ptr< Operation > copy() const override
~SsaPhiOperation() noexcept override
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
std::vector< ControlFlowGraphNode * > IncomingNodes_
std::string debug_string() const override
size_t numElements() const noexcept
std::shared_ptr< const Type > getElementType(const size_t index) const noexcept
static std::unique_ptr< llvm::ThreeAddressCode > create(std::unique_ptr< rvsdg::SimpleOperation > operation, const std::vector< const Variable * > &operands)
UndefValueOperation class.
~UndefValueOperation() noexcept override
std::string debug_string() const override
const rvsdg::Type & GetType() const noexcept
UndefValueOperation(const UndefValueOperation &)=default
std::unique_ptr< Operation > copy() const override
static std::unique_ptr< llvm::ThreeAddressCode > Create(std::unique_ptr< ThreeAddressCodeVariable > result)
static std::unique_ptr< llvm::ThreeAddressCode > Create(std::shared_ptr< const jlm::rvsdg::Type > type, const std::string &name)
bool operator==(const Operation &other) const noexcept override
UndefValueOperation & operator=(UndefValueOperation &&)=delete
UndefValueOperation & operator=(const UndefValueOperation &)=delete
static std::unique_ptr< llvm::ThreeAddressCode > Create(std::shared_ptr< const jlm::rvsdg::Type > type)
static jlm::rvsdg::Output * Create(rvsdg::Region ®ion, std::shared_ptr< const jlm::rvsdg::Type > type)
static std::shared_ptr< const VariableArgumentType > Create()
const jlm::rvsdg::Type & type() const noexcept
const std::shared_ptr< const jlm::rvsdg::Type > Type() const noexcept
static rvsdg::Output * Create(rvsdg::Region ®ion, const std::vector< rvsdg::Output * > &operands)
VariadicArgumentListOperation(const VariadicArgumentListOperation &)=default
VariadicArgumentListOperation & operator=(const VariadicArgumentListOperation &)=delete
std::string debug_string() const override
~VariadicArgumentListOperation() noexcept override
std::unique_ptr< Operation > copy() const override
static std::unique_ptr< llvm::ThreeAddressCode > create(const std::vector< const Variable * > &arguments)
VariadicArgumentListOperation & operator=(VariadicArgumentListOperation &&)=delete
bool operator==(const Operation &other) const noexcept override
bool operator==(const Operation &other) const noexcept override
std::string debug_string() const override
VectorBinaryOperation & operator=(const VectorBinaryOperation &other)
std::unique_ptr< Operation > copy() const override
VectorBinaryOperation(const VectorBinaryOperation &other)
const rvsdg::BinaryOperation & operation() const noexcept
static std::unique_ptr< llvm::ThreeAddressCode > create(const rvsdg::BinaryOperation &binop, const llvm::Variable *op1, const llvm::Variable *op2, const std::shared_ptr< const jlm::rvsdg::Type > &type)
std::unique_ptr< Operation > op_
~VectorBinaryOperation() noexcept override
VectorBinaryOperation(VectorBinaryOperation &&other) noexcept
VectorBinaryOperation & operator=(VectorBinaryOperation &&other) noexcept
size_t size() const noexcept
std::unique_ptr< Operation > copy() const override
static std::unique_ptr< ThreeAddressCode > createVectorSelectTac(const Variable *p, const Variable *t, const Variable *f)
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
std::string debug_string() const override
const rvsdg::Type & type() const noexcept
bool operator==(const Operation &other) const noexcept override
~VectorSelectOperation() noexcept override
static std::unique_ptr< llvm::ThreeAddressCode > create(const Variable *p, const Variable *t, const Variable *f)
std::unique_ptr< Operation > op_
VectorUnaryOperation & operator=(VectorUnaryOperation &&other) noexcept
bool operator==(const Operation &other) const noexcept override
~VectorUnaryOperation() noexcept override
VectorUnaryOperation(const VectorUnaryOperation &other)
std::string debug_string() const override
const rvsdg::UnaryOperation & operation() const noexcept
VectorUnaryOperation(VectorUnaryOperation &&other) noexcept
std::unique_ptr< Operation > copy() const override
VectorUnaryOperation & operator=(const VectorUnaryOperation &other)
static std::unique_ptr< llvm::ThreeAddressCode > create(const rvsdg::UnaryOperation &unop, const llvm::Variable *operand, const std::shared_ptr< const jlm::rvsdg::Type > &type)
static std::shared_ptr< const BitType > Create(std::size_t nbits)
Creates bit type of specified width.
static std::shared_ptr< const ControlType > Create(std::size_t nalternatives)
Instantiates control type.
NodeInput * input(size_t index) const noexcept
NodeOutput * output(size_t index) const noexcept
virtual const Operation & GetOperation() const noexcept=0
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
Represent acyclic RVSDG subgraphs.
NodeOutput * output(size_t index) const noexcept
const std::shared_ptr< const rvsdg::Type > & argument(size_t index) const noexcept
const std::shared_ptr< const rvsdg::Type > & result(size_t index) const noexcept
size_t nresults() const noexcept
SimpleOperation(std::vector< std::shared_ptr< const jlm::rvsdg::Type > > operands, std::vector< std::shared_ptr< const jlm::rvsdg::Type > > results)
size_t narguments() const noexcept
UnaryOperation(std::shared_ptr< const Type > operand, std::shared_ptr< const Type > result)
#define JLM_UNREACHABLE(msg)
Global memory state passed between functions.
ICmpPredicate convertICmpPredicateToJlm(::llvm::CmpInst::Predicate predicate)
std::string_view iCmpPredicateToString(ICmpPredicate predicate)
::llvm::CmpInst::Predicate convertICmpPredicateToLlvm(ICmpPredicate predicate)
size_t binop_reduction_path_t
@ Value
Designate a value type.
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
static std::string strfmt(Args... args)