6 #ifndef JLM_LLVM_IR_OPERATORS_STDLIBINTRINSICOPERATIONS_HPP
7 #define JLM_LLVM_IR_OPERATORS_STDLIBINTRINSICOPERATIONS_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>>
265 operator==(
const Operation & other)
const noexcept
override;
267 [[nodiscard]] std::string
270 [[nodiscard]] std::unique_ptr<Operation>
271 copy()
const override;
282 const std::vector<const
Variable *> & memoryStates)
284 std::vector<const Variable *>
operands = { &destination, &source, &length, &ioState };
287 auto operation = std::make_unique<MemCpyVolatileOperation>(length.Type(), memoryStates.size());
297 const std::vector<rvsdg::Output *> & memoryStates)
299 std::vector
operands = { &destination, &source, &length, &ioState };
302 return rvsdg::CreateOpNode<MemCpyVolatileOperation>(
305 memoryStates.size());
309 static std::vector<std::shared_ptr<const rvsdg::Type>>
313 std::vector<std::shared_ptr<const rvsdg::Type>> types = { pointerType,
315 std::move(lengthType),
321 static std::vector<std::shared_ptr<const rvsdg::Type>>
345 const std::vector<std::shared_ptr<const rvsdg::Type>> & operandTypes,
346 const std::vector<std::shared_ptr<const rvsdg::Type>> & resultTypes)
351 auto & dstAddressType = *operandTypes[0];
356 throw std::runtime_error(
"Expected 8 bit integer type.");
362 throw util::Error(
"Expected 32 bit or 64 bit integer type.");
365 if (
auto & memoryStateType = *operandTypes.back(); !is<MemoryStateType>(memoryStateType))
367 throw util::Error(
"Number of memory states cannot be zero.");
378 const auto type = std::dynamic_pointer_cast<const rvsdg::BitType>(
argument(2));
380 JLM_ASSERT(type->nbits() == 32 || type->nbits() == 64);
387 [[nodiscard]]
virtual size_t
394 [[nodiscard]] static rvsdg::Input &
398 const auto input = node.input(0);
411 const auto input = node.input(1);
424 const auto input = node.input(2);
438 auto [memsetNode, memsetOperation] =
439 rvsdg::TryGetSimpleNodeAndOptionalOp<MemSetOperation>(output);
441 const auto numNonMemoryStateOutputs =
442 memsetNode->noutputs() - memsetOperation->numMemoryStates();
444 const auto numNonMemoryStateInputs = memsetNode->ninputs() - memsetOperation->numMemoryStates();
445 const auto inputIndex = numNonMemoryStateInputs + (output.
index() - numNonMemoryStateOutputs);
446 const auto input = memsetNode->input(inputIndex);
447 JLM_ASSERT(is<MemoryStateType>(input->Type()));
458 auto [memsetNode, memsetOperation] =
459 rvsdg::TryGetSimpleNodeAndOptionalOp<MemSetOperation>(input);
461 const auto numNonMemoryStateInputs = memsetNode->ninputs() - memsetOperation->numMemoryStates();
463 const auto numNonMemoryStateOutputs =
464 memsetNode->noutputs() - memsetOperation->numMemoryStates();
465 const auto outputIndex = numNonMemoryStateOutputs + (input.
index() - numNonMemoryStateInputs);
466 const auto output = memsetNode->output(outputIndex);
467 JLM_ASSERT(is<MemoryStateType>(output->Type()));
490 operator==(
const Operation & other)
const noexcept
override;
492 [[nodiscard]] std::string
495 [[nodiscard]] std::unique_ptr<Operation>
496 copy()
const override;
506 const std::vector<const
Variable *> & memoryStates)
508 std::vector
operands = { &destination, &value, &length };
512 std::make_unique<MemSetNonVolatileOperation>(length.Type(), memoryStates.size());
521 const std::vector<rvsdg::Output *> & memoryStates)
523 std::vector
operands = { &destination, &value, &length };
526 return rvsdg::CreateOpNode<MemSetNonVolatileOperation>(
529 memoryStates.size());
533 static std::vector<std::shared_ptr<const rvsdg::Type>>
535 const std::shared_ptr<const rvsdg::Type> &
lengthType,
540 std::vector<std::shared_ptr<const rvsdg::Type>> types = { pointerType, valueType,
lengthType };
545 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::vector< std::shared_ptr< const rvsdg::Type > > createOperandTypes(const std::shared_ptr< const rvsdg::Type > &lengthType, const size_t numMemoryStates)
size_t numMemoryStates() const noexcept override
~MemSetNonVolatileOperation() noexcept override
std::string debug_string() const override
bool operator==(const Operation &other) const noexcept override
static std::vector< std::shared_ptr< const rvsdg::Type > > createResultTypes(size_t numMemoryStates)
static rvsdg::SimpleNode & createNode(rvsdg::Output &destination, rvsdg::Output &value, rvsdg::Output &length, const std::vector< rvsdg::Output * > &memoryStates)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &destination, const Variable &value, const Variable &length, const std::vector< const Variable * > &memoryStates)
std::unique_ptr< Operation > copy() const override
virtual size_t numMemoryStates() const noexcept=0
static rvsdg::Input & mapMemoryStateOutputToInput(const rvsdg::Output &output)
const rvsdg::BitType & lengthType() const noexcept
MemSetOperation(const std::vector< std::shared_ptr< const rvsdg::Type >> &operandTypes, const std::vector< std::shared_ptr< const rvsdg::Type >> &resultTypes)
static rvsdg::Input & destinationInput(const rvsdg::Node &node) noexcept
static rvsdg::Input & lengthInput(const rvsdg::Node &node) noexcept
static rvsdg::Output & mapMemoryStateInputToOutput(const rvsdg::Input &input)
static rvsdg::Input & valueInput(const rvsdg::Node &node) noexcept
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::vector< jlm::rvsdg::Output * > operands(const Node *node)
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)