6 #ifndef JLM_LLVM_IR_OPERATORS_CALL_HPP
7 #define JLM_LLVM_IR_OPERATORS_CALL_HPP
133 auto argument = jlm::util::assertedCast<jlm::rvsdg::RegionArgument>(
Output_);
139 return *argument->region()->result(argument->index())->origin();
152 return *jlm::util::assertedCast<rvsdg::RegionArgument>(
Output_);
192 static std::unique_ptr<CallTypeClassifier>
195 rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(output);
208 static std::unique_ptr<CallTypeClassifier>
223 static std::unique_ptr<CallTypeClassifier>
236 static std::unique_ptr<CallTypeClassifier>
256 std::shared_ptr<const rvsdg::FunctionType> functionType,
266 operator==(
const Operation & other)
const noexcept
override;
268 [[nodiscard]] std::string
271 [[nodiscard]]
const std::shared_ptr<const rvsdg::FunctionType> &
289 [[nodiscard]] std::unique_ptr<Operation>
290 copy()
const override;
297 [[nodiscard]]
static size_t
301 return node.ninputs() - 1;
314 return node.
input(n + 1);
324 const auto functionInput = node.input(0);
325 JLM_ASSERT(is<rvsdg::FunctionType>(functionInput->Type()));
326 return *functionInput;
336 const auto ioState = node.input(node.ninputs() - 2);
348 const auto ioState = node.output(node.noutputs() - 2);
360 const auto memoryState = node.input(node.ninputs() - 1);
361 JLM_ASSERT(is<MemoryStateType>(memoryState->Type()));
372 const auto memoryState = node.output(node.noutputs() - 1);
373 JLM_ASSERT(is<MemoryStateType>(memoryState->Type()));
393 return is<CallEntryMemoryStateMergeOperation>(node) ? node :
nullptr;
417 return is<CallExitMemoryStateSplitOperation>(node) ? node :
nullptr;
441 static std::unique_ptr<CallTypeClassifier>
444 static std::unique_ptr<ThreeAddressCode>
447 std::shared_ptr<const rvsdg::FunctionType> functionType,
450 const std::vector<const Variable *> & arguments)
454 auto op = std::make_unique<CallOperation>(
455 std::move(functionType),
457 std::move(attributes));
458 std::vector<const Variable *>
operands({
function });
463 static std::vector<rvsdg::Output *>
466 std::shared_ptr<const rvsdg::FunctionType> functionType,
467 const std::vector<rvsdg::Output *> & arguments)
472 static std::vector<rvsdg::Output *>
475 std::shared_ptr<const rvsdg::FunctionType> functionType,
478 const std::vector<rvsdg::Output *> & arguments)
482 std::move(functionType),
484 std::move(attributes),
491 std::unique_ptr<CallOperation> callOperation,
492 const std::vector<rvsdg::Output *> &
operands)
507 std::shared_ptr<const rvsdg::FunctionType> functionType,
508 const std::vector<rvsdg::Output *> & arguments)
512 std::move(functionType),
521 std::shared_ptr<const rvsdg::FunctionType> functionType,
524 const std::vector<rvsdg::Output *> & arguments)
528 auto callOperation = std::make_unique<CallOperation>(
529 std::move(functionType),
531 std::move(attributes));
539 static inline std::vector<std::shared_ptr<const rvsdg::Type>>
542 std::vector<std::shared_ptr<const rvsdg::Type>> types({ functionType });
543 for (
auto & argumentType : functionType->Arguments())
544 types.emplace_back(argumentType);
552 if (!is<rvsdg::FunctionType>(type))
562 throw util::Error(
"Expected at least three argument types.");
564 auto memoryStateArgumentIndex = functionType.
NumArguments() - 1;
565 auto iOStateArgumentIndex = functionType.
NumArguments() - 2;
567 if (!is<MemoryStateType>(functionType.
ArgumentType(memoryStateArgumentIndex)))
570 if (!is<IOStateType>(functionType.
ArgumentType(iOStateArgumentIndex)))
577 throw util::Error(
"Expected at least three result types.");
579 auto memoryStateResultIndex = functionType.
NumResults() - 1;
580 auto iOStateResultIndex = functionType.
NumResults() - 2;
582 if (!is<MemoryStateType>(functionType.
ResultType(memoryStateResultIndex)))
585 if (!is<IOStateType>(functionType.
ResultType(iOStateResultIndex)))
589 CheckArgumentTypes(functionType);
590 CheckResultTypes(functionType);
static AttributeList createEmptyList()
CallingConvention getCallingConvention() const noexcept
static rvsdg::Input * Argument(const rvsdg::Node &node, const size_t n)
~CallOperation() override
static rvsdg::Input & GetIOStateInput(const rvsdg::Node &node) noexcept
static rvsdg::SimpleNode & CreateNode(rvsdg::Region ®ion, std::unique_ptr< CallOperation > callOperation, const std::vector< rvsdg::Output * > &operands)
std::shared_ptr< const rvsdg::FunctionType > FunctionType_
static rvsdg::SimpleNode * tryGetMemoryStateExitSplit(const rvsdg::Node &callNode) noexcept
static rvsdg::Input & GetFunctionInput(const rvsdg::Node &node) noexcept
const std::shared_ptr< const rvsdg::FunctionType > & GetFunctionType() const noexcept
static std::vector< std::shared_ptr< const rvsdg::Type > > create_srctypes(const std::shared_ptr< const rvsdg::FunctionType > &functionType)
std::unique_ptr< Operation > copy() const override
static rvsdg::SimpleNode & CreateNode(rvsdg::Output *function, std::shared_ptr< const rvsdg::FunctionType > functionType, CallingConvention callingConvention, AttributeList attributes, const std::vector< rvsdg::Output * > &arguments)
static std::unique_ptr< CallTypeClassifier > ClassifyCall(const rvsdg::SimpleNode &callNode)
Classifies a call node.
static rvsdg::Input & GetMemoryStateInput(const rvsdg::Node &node) noexcept
const AttributeList & getAttributes() const noexcept
static void CheckFunctionInputType(const jlm::rvsdg::Type &type)
static size_t NumArguments(const rvsdg::Node &node) noexcept
static rvsdg::Output & TraceFunctionInput(const rvsdg::SimpleNode &callNode)
Traces function input of call node.
static rvsdg::Output & GetIOStateOutput(const rvsdg::Node &node) noexcept
static void CheckFunctionType(const rvsdg::FunctionType &functionType)
bool operator==(const Operation &other) const noexcept override
CallOperation(std::shared_ptr< const rvsdg::FunctionType > functionType, CallingConvention callingConvention, AttributeList attributes)
static std::unique_ptr< ThreeAddressCode > create(const Variable *function, std::shared_ptr< const rvsdg::FunctionType > functionType, CallingConvention callingConvention, AttributeList attributes, const std::vector< const Variable * > &arguments)
static rvsdg::Output & GetMemoryStateOutput(const rvsdg::Node &node) noexcept
std::string debug_string() const override
static std::vector< rvsdg::Output * > Create(rvsdg::Output *function, std::shared_ptr< const rvsdg::FunctionType > functionType, CallingConvention callingConvention, AttributeList attributes, const std::vector< rvsdg::Output * > &arguments)
AttributeList attributes_
static rvsdg::SimpleNode & CreateNode(rvsdg::Output *function, std::shared_ptr< const rvsdg::FunctionType > functionType, const std::vector< rvsdg::Output * > &arguments)
static rvsdg::SimpleNode * tryGetMemoryStateEntryMerge(const rvsdg::Node &callNode) noexcept
CallingConvention callingConvention_
static std::vector< rvsdg::Output * > Create(rvsdg::Output *function, std::shared_ptr< const rvsdg::FunctionType > functionType, const std::vector< rvsdg::Output * > &arguments)
rvsdg::Output & GetLambdaOutput() const noexcept
Returns the called function.
bool IsExternalCall() const noexcept
Determines whether call is an external call.
jlm::rvsdg::Output * Output_
static std::unique_ptr< CallTypeClassifier > CreateExternalCallClassifier(rvsdg::RegionArgument &argument)
Classify callee as external.
static std::unique_ptr< CallTypeClassifier > CreateIndirectCallClassifier(jlm::rvsdg::Output &output)
Classify callee as inderict.
bool IsIndirectCall() const noexcept
Determines whether call is an indirect call.
CallTypeClassifier(CallType callType, jlm::rvsdg::Output &output)
static std::unique_ptr< CallTypeClassifier > CreateNonRecursiveDirectCallClassifier(rvsdg::Output &output)
Classify callee as non-recursive.
bool IsNonRecursiveDirectCall() const noexcept
Determines whether call is a non-recursive direct call.
CallType GetCallType() const noexcept
Return call type.
rvsdg::RegionArgument & GetImport() const noexcept
Returns the imported function.
static std::unique_ptr< CallTypeClassifier > CreateRecursiveDirectCallClassifier(rvsdg::Output &output)
Classify callee as recursive.
bool IsRecursiveDirectCall() const noexcept
Determines whether call is a recursive direct call.
bool IsDirectCall() const noexcept
jlm::rvsdg::Output & GetFunctionOrigin() const noexcept
Return origin of a call node's function input.
static std::unique_ptr< llvm::ThreeAddressCode > create(std::unique_ptr< rvsdg::SimpleOperation > operation, const std::vector< const Variable * > &operands)
size_t NumArguments() const noexcept
size_t NumResults() const noexcept
const jlm::rvsdg::Type & ArgumentType(size_t index) const noexcept
const jlm::rvsdg::Type & ResultType(size_t index) const noexcept
Region & GetRootRegion() const noexcept
NodeInput * input(size_t index) const noexcept
rvsdg::Region * region() const noexcept
Represents the argument of a region.
Represent acyclic RVSDG subgraphs.
Graph * graph() const noexcept
static SimpleNode & Create(Region ®ion, std::unique_ptr< Operation > operation, const std::vector< rvsdg::Output * > &operands)
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)