6 #ifndef JLM_LLVM_IR_OPERATORS_MEMORYSTATEOPERATIONS_HPP
7 #define JLM_LLVM_IR_OPERATORS_MEMORYSTATEOPERATIONS_HPP
47 throw util::Error(
"Insufficient number of operands.");
51 operator==(
const Operation & other)
const noexcept
override;
53 [[nodiscard]] std::string
56 [[nodiscard]] std::unique_ptr<Operation>
57 copy()
const override;
67 static std::optional<std::vector<rvsdg::Output *>>
70 const std::vector<rvsdg::Output *> &
operands);
78 static std::optional<std::vector<rvsdg::Output *>>
81 const std::vector<rvsdg::Output *> &
operands);
90 static std::optional<std::vector<rvsdg::Output *>>
93 const std::vector<rvsdg::Output *> &
operands);
102 static std::optional<std::vector<rvsdg::Output *>>
105 const std::vector<rvsdg::Output *> &
operands);
110 return rvsdg::CreateOpNode<MemoryStateMergeOperation>(
operands,
operands.size());
119 static std::unique_ptr<ThreeAddressCode>
123 throw util::Error(
"Insufficient number of operands.");
125 auto operation = std::make_unique<MemoryStateMergeOperation>(
operands.size());
144 if (numOperands == 0)
145 throw std::logic_error(
"Insufficient number of operands.");
149 operator==(
const Operation & other)
const noexcept
override;
151 [[nodiscard]] std::string
154 [[nodiscard]] std::unique_ptr<Operation>
155 copy()
const override;
165 static std::optional<std::vector<rvsdg::Output *>>
168 const std::vector<rvsdg::Output *> &
operands);
176 static std::optional<std::vector<rvsdg::Output *>>
179 const std::vector<rvsdg::Output *> &
operands);
188 static std::optional<std::vector<rvsdg::Output *>>
191 const std::vector<rvsdg::Output *> &
operands);
196 return rvsdg::CreateOpNode<MemoryStateJoinOperation>(
operands,
operands.size());
215 throw util::Error(
"Insufficient number of results.");
219 operator==(
const Operation & other)
const noexcept
override;
221 [[nodiscard]] std::string
224 [[nodiscard]] std::unique_ptr<Operation>
225 copy()
const override;
235 static std::optional<std::vector<rvsdg::Output *>>
238 const std::vector<rvsdg::Output *> &
operands);
247 static std::optional<std::vector<rvsdg::Output *>>
250 const std::vector<rvsdg::Output *> &
operands);
260 static std::optional<std::vector<rvsdg::Output *>>
263 const std::vector<rvsdg::Output *> &
operands);
268 return rvsdg::CreateOpNode<MemoryStateSplitOperation>({ &operand }, numResults);
271 static std::vector<rvsdg::Output *>
296 operator==(const Operation & other) const noexcept override;
298 [[nodiscard]] std::
string
301 [[nodiscard]] std::unique_ptr<Operation>
302 copy() const override;
310 std::vector<MemoryNodeId> memoryNodeIds(
nresults());
314 memoryNodeIds[index] = memoryNodeId;
317 return memoryNodeIds;
355 static std::optional<std::vector<rvsdg::Output *>>
358 const std::vector<rvsdg::Output *> &
operands);
363 return rvsdg::CreateOpNode<LambdaEntryMemoryStateSplitOperation>(
365 std::move(memoryNodeIds));
390 operator==(const Operation & other) const noexcept override;
392 [[nodiscard]] std::
string
395 [[nodiscard]] std::unique_ptr<Operation>
396 copy() const override;
404 std::vector<MemoryNodeId> memoryNodeIds(
narguments());
408 memoryNodeIds[index] = memoryNodeId;
411 return memoryNodeIds;
448 static std::optional<std::vector<rvsdg::Output *>>
451 const std::vector<rvsdg::Output *> &
operands);
464 static std::optional<std::vector<rvsdg::Output *>>
467 const std::vector<rvsdg::Output *> &
operands);
479 static std::optional<std::vector<rvsdg::Output *>>
482 const std::vector<rvsdg::Output *> &
operands);
487 const std::vector<rvsdg::Output *> &
operands,
488 const std::vector<MemoryNodeId> & memoryNodeIds)
491 ? rvsdg::CreateOpNode<LambdaExitMemoryStateMergeOperation>(region, memoryNodeIds)
492 : rvsdg::CreateOpNode<LambdaExitMemoryStateMergeOperation>(
operands, memoryNodeIds);
517 operator==(const Operation & other) const noexcept override;
519 [[nodiscard]] std::
string
522 [[nodiscard]] std::unique_ptr<Operation>
523 copy() const override;
531 std::vector<MemoryNodeId> memoryNodeIds(
narguments());
535 memoryNodeIds[index] = memoryNodeId;
538 return memoryNodeIds;
555 const std::vector<rvsdg::Output *> &
operands,
556 std::vector<MemoryNodeId> memoryNodeIds)
558 return operands.empty() ? rvsdg::CreateOpNode<CallEntryMemoryStateMergeOperation>(
560 std::move(memoryNodeIds))
561 : rvsdg::CreateOpNode<CallEntryMemoryStateMergeOperation>(
563 std::move(memoryNodeIds));
588 operator==(const Operation & other) const noexcept override;
590 [[nodiscard]] std::
string
593 [[nodiscard]] std::unique_ptr<Operation>
594 copy() const override;
602 std::vector<MemoryNodeId> memoryNodeIds(
nresults());
606 memoryNodeIds[index] = memoryNodeId;
609 return memoryNodeIds;
647 static std::optional<std::vector<rvsdg::Output *>>
650 const std::vector<rvsdg::Output *> &
operands);
655 return rvsdg::CreateOpNode<CallExitMemoryStateSplitOperation>(
657 std::move(memoryNodeIds));
static rvsdg::SimpleNode & CreateNode(rvsdg::Region ®ion, const std::vector< rvsdg::Output * > &operands, std::vector< MemoryNodeId > memoryNodeIds)
std::string debug_string() const override
util::BijectiveMap< MemoryNodeId, size_t > MemoryNodeIdToIndex_
std::unique_ptr< Operation > copy() const override
~CallEntryMemoryStateMergeOperation() noexcept override
std::vector< MemoryNodeId > getMemoryNodeIds() const noexcept
static rvsdg::Input * tryMapMemoryNodeIdToInput(const rvsdg::SimpleNode &node, MemoryNodeId memoryNodeId)
~CallExitMemoryStateSplitOperation() noexcept override
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &operand, std::vector< MemoryNodeId > memoryNodeIds)
static MemoryNodeId mapOutputToMemoryNodeId(const rvsdg::Output &output)
static std::optional< std::vector< rvsdg::Output * > > NormalizeLambdaExitMemoryStateMerge(const CallExitMemoryStateSplitOperation &callExitSplitOperation, const std::vector< rvsdg::Output * > &operands)
util::BijectiveMap< MemoryNodeId, size_t > memoryNodeIdToIndexMap_
std::unique_ptr< Operation > copy() const override
static rvsdg::Output * tryMapMemoryNodeIdToOutput(const rvsdg::SimpleNode &node, MemoryNodeId memoryNodeId)
std::string debug_string() const override
std::vector< MemoryNodeId > getMemoryNodeIds() const noexcept
util::BijectiveMap< MemoryNodeId, size_t > memoryNodeIdToIndexMap_
static rvsdg::Output * tryMapMemoryNodeIdToOutput(const rvsdg::SimpleNode &node, MemoryNodeId memoryNodeId)
~LambdaEntryMemoryStateSplitOperation() noexcept override
std::vector< MemoryNodeId > getMemoryNodeIds() const noexcept
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &operand, std::vector< MemoryNodeId > memoryNodeIds)
static std::optional< std::vector< rvsdg::Output * > > NormalizeCallEntryMemoryStateMerge(const LambdaEntryMemoryStateSplitOperation &lambdaEntrySplitOperation, const std::vector< rvsdg::Output * > &operands)
std::unique_ptr< Operation > copy() const override
static MemoryNodeId mapOutputToMemoryNodeId(const rvsdg::Output &output)
std::string debug_string() const override
static std::optional< std::vector< rvsdg::Output * > > NormalizeLoadFromAlloca(const LambdaExitMemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::vector< MemoryNodeId > getMemoryNodeIds() const noexcept
static std::optional< std::vector< rvsdg::Output * > > NormalizeStoreToAlloca(const LambdaExitMemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
util::BijectiveMap< MemoryNodeId, size_t > MemoryNodeIdToIndex_
static rvsdg::Input * tryMapMemoryNodeIdToInput(const rvsdg::SimpleNode &node, MemoryNodeId memoryNodeId)
static rvsdg::Node & CreateNode(rvsdg::Region ®ion, const std::vector< rvsdg::Output * > &operands, const std::vector< MemoryNodeId > &memoryNodeIds)
std::unique_ptr< Operation > copy() const override
static std::optional< std::vector< rvsdg::Output * > > NormalizeAlloca(const LambdaExitMemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
~LambdaExitMemoryStateMergeOperation() noexcept override
static MemoryNodeId mapInputToMemoryNodeId(const rvsdg::Input &input)
std::string debug_string() const override
std::unique_ptr< Operation > copy() const override
static std::optional< std::vector< rvsdg::Output * > > NormalizeDuplicateOperands(const MemoryStateJoinOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes duplicated operands from the MemoryStateJoinOperation.
static std::optional< std::vector< rvsdg::Output * > > NormalizeNestedJoins(const MemoryStateJoinOperation &operation, const std::vector< rvsdg::Output * > &operands)
Fuses nested MemoryStateJoinOperation nodes into a single node.
static std::optional< std::vector< rvsdg::Output * > > NormalizeSingleOperand(const MemoryStateJoinOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes the MemoryStateJoinOperation as it has only a single operand, i.e., no joining is performed.
bool operator==(const Operation &other) const noexcept override
std::string debug_string() const override
static rvsdg::SimpleNode & CreateNode(const std::vector< rvsdg::Output * > &operands)
~MemoryStateJoinOperation() noexcept override
static std::optional< std::vector< rvsdg::Output * > > NormalizeNestedMerges(const MemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
Fuses nested merges into a single merge.
bool operator==(const Operation &other) const noexcept override
static rvsdg::SimpleNode & CreateNode(const std::vector< rvsdg::Output * > &operands)
static rvsdg::Output * Create(const std::vector< rvsdg::Output * > &operands)
~MemoryStateMergeOperation() noexcept override
std::unique_ptr< Operation > copy() const override
static std::optional< std::vector< rvsdg::Output * > > NormalizeMergeSplit(const MemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
Fuses nested splits into a single merge.
static std::optional< std::vector< rvsdg::Output * > > NormalizeSingleOperand(const MemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes the MemoryStateMergeOperation as it has only a single operand, i.e., no merging is performed.
static std::unique_ptr< ThreeAddressCode > Create(const std::vector< const Variable * > &operands)
static std::optional< std::vector< rvsdg::Output * > > NormalizeDuplicateOperands(const MemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes duplicated operands from the MemoryStateMergeOperation.
std::string debug_string() const override
MemoryStateOperation(size_t numOperands, size_t numResults)
static std::optional< std::vector< rvsdg::Output * > > NormalizeNestedSplits(const MemoryStateSplitOperation &operation, const std::vector< rvsdg::Output * > &operands)
Fuses nested splits into a single split.
~MemoryStateSplitOperation() noexcept override
bool operator==(const Operation &other) const noexcept override
static std::optional< std::vector< rvsdg::Output * > > NormalizeSingleResult(const MemoryStateSplitOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes the MemoryStateSplitOperation as it has only a single result, i.e., no splitting is performed...
static std::vector< rvsdg::Output * > Create(rvsdg::Output &operand, const size_t numResults)
std::unique_ptr< Operation > copy() const override
std::string debug_string() const override
static std::optional< std::vector< rvsdg::Output * > > NormalizeSplitMerge(const MemoryStateSplitOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes an idempotent split-merge pair.
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &operand, const size_t numResults)
static std::shared_ptr< const MemoryStateType > Create()
static std::unique_ptr< llvm::ThreeAddressCode > create(std::unique_ptr< rvsdg::SimpleOperation > operation, const std::vector< const Variable * > &operands)
Represent acyclic RVSDG subgraphs.
NodeOutput * output(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
Global memory state passed between functions.
bool hasMemoryState(const rvsdg::Node &node)
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)