6 #ifndef JLM_LLVM_IR_OPERATORS_AGGREGATEOPERATIONS_HPP
7 #define JLM_LLVM_IR_OPERATORS_AGGREGATEOPERATIONS_HPP
31 const std::shared_ptr<const rvsdg::Type> & aggtype,
32 const std::vector<
unsigned> & indices)
41 operator==(
const Operation & other)
const noexcept
override;
43 [[nodiscard]] std::string
46 [[nodiscard]] std::unique_ptr<Operation>
47 copy()
const override;
67 static std::unique_ptr<ThreeAddressCode>
70 auto op = std::make_unique<ExtractValueOperation>(
aggregate->Type(), indices);
75 static std::vector<std::shared_ptr<const rvsdg::Type>>
76 dsttype(
const std::shared_ptr<const rvsdg::Type> & aggtype,
const std::vector<unsigned> & indices)
78 std::shared_ptr<const rvsdg::Type>
type = aggtype;
79 for (
const auto & index : indices)
81 if (
auto st = std::dynamic_pointer_cast<const StructType>(
type))
83 if (index >= st->numElements())
84 throw util::Error(
"extractvalue index out of bound.");
86 type = st->getElementType(index);
88 else if (
auto at = std::dynamic_pointer_cast<const ArrayType>(
type))
90 if (index >= at->nelements())
91 throw util::Error(
"extractvalue index out of bound.");
93 type = at->GetElementType();
96 throw util::Error(
"expected struct or array type.");
118 const std::shared_ptr<const rvsdg::Type> & aggregateType,
119 const std::shared_ptr<const rvsdg::Type> & valueType,
120 std::vector<
unsigned> indices)
126 [[nodiscard]]
const std::shared_ptr<const rvsdg::Type> &
132 [[nodiscard]]
const std::shared_ptr<const rvsdg::Type> &
138 [[nodiscard]]
const std::vector<unsigned> &
145 operator==(
const Operation & other)
const noexcept
override;
150 [[nodiscard]] std::unique_ptr<Operation>
151 copy()
const override;
153 static std::unique_ptr<InsertValueOperation>
155 const std::shared_ptr<const rvsdg::Type> & aggregateType,
156 const std::shared_ptr<const rvsdg::Type> & valueType,
157 std::vector<unsigned> indices)
160 return std::unique_ptr<InsertValueOperation>(
168 std::vector<unsigned> indices)
170 auto insertValueOperation =
171 create(aggregateOperand.
Type(), valueOperand.
Type(), std::move(indices));
173 *aggregateOperand.
region(),
174 std::move(insertValueOperation),
175 { &aggregateOperand, &valueOperand });
178 static std::unique_ptr<ThreeAddressCode>
182 std::vector<unsigned> indices)
184 auto insertValueOperation =
185 create(aggregateOperand.
Type(), valueOperand.
Type(), std::move(indices));
187 std::move(insertValueOperation),
188 { &aggregateOperand, &valueOperand });
194 const std::shared_ptr<const rvsdg::Type> & aggregateType,
195 const std::shared_ptr<const rvsdg::Type> & valueType,
196 const std::vector<unsigned> & indices)
200 throw std::runtime_error(
"indices are empty.");
203 auto type = aggregateType;
204 for (
const auto & index : indices)
206 if (
const auto structType = std::dynamic_pointer_cast<const StructType>(type))
208 if (index >= structType->numElements())
209 throw util::Error(
"insertvalue index out of bound.");
211 type = structType->getElementType(index);
213 else if (
const auto arrayType = std::dynamic_pointer_cast<const ArrayType>(type))
215 if (index >= arrayType->nelements())
216 throw util::Error(
"insertvalue index out of bound.");
218 type = arrayType->GetElementType();
222 throw std::runtime_error(
"expected array or struct type.");
226 if (*valueType != *type)
228 throw std::runtime_error(
"value operand does not have the right type.");
static rvsdg::SimpleNode & createNode(rvsdg::Output &aggregateOperand, rvsdg::Output &valueOperand, std::vector< unsigned > indices)
~InsertValueOperation() noexcept override
std::string debug_string() const override
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &aggregateOperand, const Variable &valueOperand, std::vector< unsigned > indices)
std::unique_ptr< Operation > copy() const override
const std::vector< unsigned > & getIndices() const noexcept
bool operator==(const Operation &other) const noexcept override
std::vector< unsigned > indices_
const std::shared_ptr< const rvsdg::Type > & getValueType() const noexcept
const std::shared_ptr< const rvsdg::Type > & getAggregateType() const noexcept
static void checkOperandTypes(const std::shared_ptr< const rvsdg::Type > &aggregateType, const std::shared_ptr< const rvsdg::Type > &valueType, const std::vector< unsigned > &indices)
InsertValueOperation(const std::shared_ptr< const rvsdg::Type > &aggregateType, const std::shared_ptr< const rvsdg::Type > &valueType, std::vector< unsigned > indices)
static std::unique_ptr< InsertValueOperation > create(const std::shared_ptr< const rvsdg::Type > &aggregateType, const std::shared_ptr< const rvsdg::Type > &valueType, std::vector< unsigned > indices)
static std::unique_ptr< llvm::ThreeAddressCode > create(std::unique_ptr< rvsdg::SimpleOperation > operation, const std::vector< const Variable * > &operands)
const std::shared_ptr< const jlm::rvsdg::Type > Type() const noexcept
rvsdg::Region * region() const noexcept
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
static SimpleNode & Create(Region ®ion, std::unique_ptr< Operation > operation, const std::vector< rvsdg::Output * > &operands)
const std::shared_ptr< const rvsdg::Type > & argument(size_t index) const noexcept
SimpleOperation(std::vector< std::shared_ptr< const jlm::rvsdg::Type >> operands, std::vector< std::shared_ptr< const jlm::rvsdg::Type >> results)
Global memory state passed between functions.
static ControlFlowGraphNode * aggregate(ControlFlowGraphNode *, ControlFlowGraphNode *, AggregationMap &)