6 #ifndef JLM_LLVM_IR_OPERATORS_MEMCPY_HPP
7 #define JLM_LLVM_IR_OPERATORS_MEMCPY_HPP
27 const std::vector<std::shared_ptr<const rvsdg::Type>> & operandTypes,
28 const std::vector<std::shared_ptr<const rvsdg::Type>> & resultTypes)
33 auto & dstAddressType = *operandTypes[0];
36 auto & srcAddressType = *operandTypes[1];
39 auto & lengthType = *operandTypes[2];
42 throw util::Error(
"Expected 32 bit or 64 bit integer type.");
45 auto & memoryStateType = *operandTypes.back();
46 if (!is<MemoryStateType>(memoryStateType))
48 throw util::Error(
"Number of memory states cannot be zero.");
56 auto type = std::dynamic_pointer_cast<const rvsdg::BitType>(
argument(2));
61 [[nodiscard]]
virtual size_t
68 [[nodiscard]] static rvsdg::Input &
72 const auto input = node.input(0);
85 const auto input = node.input(1);
98 const auto input = node.input(2);
110 auto [memCpyNode, memCpyOperation] =
111 rvsdg::TryGetSimpleNodeAndOptionalOp<MemCpyOperation>(output);
113 const auto numNonMemoryStateOutputs =
114 memCpyNode->noutputs() - memCpyOperation->NumMemoryStates();
116 const auto numNonMemoryStateInputs = memCpyNode->ninputs() - memCpyOperation->NumMemoryStates();
117 const auto inputIndex = numNonMemoryStateInputs + (output.
index() - numNonMemoryStateOutputs);
118 const auto input = memCpyNode->input(inputIndex);
119 JLM_ASSERT(is<MemoryStateType>(input->Type()));
130 auto [memCpyNode, memCpyOperation] =
131 rvsdg::TryGetSimpleNodeAndOptionalOp<MemCpyOperation>(input);
133 const auto numNonMemoryStateInputs = memCpyNode->ninputs() - memCpyOperation->NumMemoryStates();
135 const auto numNonMemoryStateOutputs =
136 memCpyNode->noutputs() - memCpyOperation->NumMemoryStates();
137 const auto outputIndex = numNonMemoryStateOutputs + (input.
index() - numNonMemoryStateInputs);
138 const auto output = memCpyNode->output(outputIndex);
139 JLM_ASSERT(is<MemoryStateType>(output->Type()));
161 operator==(
const Operation & other)
const noexcept
override;
163 [[nodiscard]] std::string
166 [[nodiscard]] std::unique_ptr<Operation>
167 copy()
const override;
177 const std::vector<const
Variable *> & memoryStates)
179 std::vector<const Variable *>
operands = { destination, source, length };
183 std::make_unique<MemCpyNonVolatileOperation>(length->Type(), memoryStates.size());
192 const std::vector<rvsdg::Output *> & memoryStates)
194 std::vector
operands = { &destination, &source, &length };
197 return rvsdg::CreateOpNode<MemCpyNonVolatileOperation>(
200 memoryStates.size());
203 static std::vector<rvsdg::Output *>
208 const std::vector<rvsdg::Output *> & memoryStates)
210 std::vector
operands = { destination, source, length };
213 return outputs(&rvsdg::CreateOpNode<MemCpyNonVolatileOperation>(
216 memoryStates.size()));
220 static std::vector<std::shared_ptr<const rvsdg::Type>>
224 std::vector<std::shared_ptr<const rvsdg::Type>> types = { pointerType, pointerType, length };
229 static std::vector<std::shared_ptr<const rvsdg::Type>>
259 operator==(
const Operation & other)
const noexcept
override;
261 [[nodiscard]] std::string
264 [[nodiscard]] std::unique_ptr<Operation>
265 copy()
const override;
276 const std::vector<const
Variable *> & memoryStates)
278 std::vector<const Variable *>
operands = { &destination, &source, &length, &ioState };
281 auto operation = std::make_unique<MemCpyVolatileOperation>(length.Type(), memoryStates.size());
291 const std::vector<rvsdg::Output *> & memoryStates)
293 std::vector
operands = { &destination, &source, &length, &ioState };
296 return rvsdg::CreateOpNode<MemCpyVolatileOperation>(
299 memoryStates.size());
303 static std::vector<std::shared_ptr<const rvsdg::Type>>
307 std::vector<std::shared_ptr<const rvsdg::Type>> types = { pointerType,
309 std::move(lengthType),
315 static std::vector<std::shared_ptr<const rvsdg::Type>>
static std::shared_ptr< const IOStateType > Create()
std::unique_ptr< Operation > copy() const override
MemCpyNonVolatileOperation(std::shared_ptr< const rvsdg::Type > lengthType, size_t numMemoryStates)
std::string debug_string() const override
static std::vector< std::shared_ptr< const rvsdg::Type > > CreateOperandTypes(std::shared_ptr< const rvsdg::Type > length, size_t numMemoryStates)
~MemCpyNonVolatileOperation() override
size_t NumMemoryStates() const noexcept override
static std::vector< std::shared_ptr< const rvsdg::Type > > CreateResultTypes(size_t numMemoryStates)
static std::vector< rvsdg::Output * > create(rvsdg::Output *destination, rvsdg::Output *source, rvsdg::Output *length, const std::vector< rvsdg::Output * > &memoryStates)
bool operator==(const Operation &other) const noexcept override
static rvsdg::SimpleNode & createNode(rvsdg::Output &destination, rvsdg::Output &source, rvsdg::Output &length, const std::vector< rvsdg::Output * > &memoryStates)
static std::unique_ptr< llvm::ThreeAddressCode > create(const Variable *destination, const Variable *source, const Variable *length, const std::vector< const Variable * > &memoryStates)
const rvsdg::BitType & LengthType() const noexcept
static rvsdg::Input & mapMemoryStateOutputToInput(const rvsdg::Output &output)
static rvsdg::Input & destinationInput(const rvsdg::Node &node) noexcept
virtual size_t NumMemoryStates() const noexcept=0
MemCpyOperation(const std::vector< std::shared_ptr< const rvsdg::Type >> &operandTypes, const std::vector< std::shared_ptr< const rvsdg::Type >> &resultTypes)
static rvsdg::Input & countInput(const rvsdg::Node &node) noexcept
static rvsdg::Input & sourceInput(const rvsdg::Node &node) noexcept
static rvsdg::Output & mapMemoryStateInputToOutput(const rvsdg::Input &input)
std::string debug_string() const override
static std::vector< std::shared_ptr< const rvsdg::Type > > CreateOperandTypes(std::shared_ptr< const rvsdg::Type > lengthType, size_t numMemoryStates)
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &destination, rvsdg::Output &source, rvsdg::Output &length, rvsdg::Output &ioState, const std::vector< rvsdg::Output * > &memoryStates)
static std::unique_ptr< llvm::ThreeAddressCode > CreateThreeAddressCode(const Variable &destination, const Variable &source, const Variable &length, const Variable &ioState, const std::vector< const Variable * > &memoryStates)
std::unique_ptr< Operation > copy() const override
~MemCpyVolatileOperation() noexcept override
static std::vector< std::shared_ptr< const rvsdg::Type > > CreateResultTypes(size_t numMemoryStates)
bool operator==(const Operation &other) const noexcept override
size_t NumMemoryStates() const noexcept override
static std::shared_ptr< const MemoryStateType > Create()
static std::shared_ptr< const PointerType > Create()
static std::unique_ptr< llvm::ThreeAddressCode > create(std::unique_ptr< rvsdg::SimpleOperation > operation, const std::vector< const Variable * > &operands)
static std::shared_ptr< const BitType > Create(std::size_t nbits)
Creates bit type of specified width.
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
size_t index() const noexcept
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 std::string type(const Node *n)
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)