6 #ifndef JLM_LLVM_IR_OPERATORS_CALL_HPP
7 #define JLM_LLVM_IR_OPERATORS_CALL_HPP
131 auto argument = jlm::util::assertedCast<jlm::rvsdg::RegionArgument>(
Output_);
137 return *argument->region()->result(argument->index())->origin();
150 return *jlm::util::assertedCast<rvsdg::RegionArgument>(
Output_);
190 static std::unique_ptr<CallTypeClassifier>
193 rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(output);
206 static std::unique_ptr<CallTypeClassifier>
221 static std::unique_ptr<CallTypeClassifier>
234 static std::unique_ptr<CallTypeClassifier>
253 explicit CallOperation(std::shared_ptr<const rvsdg::FunctionType> functionType)
259 operator==(
const Operation & other)
const noexcept
override;
261 [[nodiscard]] std::string
264 [[nodiscard]]
const std::shared_ptr<const rvsdg::FunctionType> &
270 [[nodiscard]] std::unique_ptr<Operation>
271 copy()
const override;
278 [[nodiscard]]
static size_t
282 return node.ninputs() - 1;
295 return node.
input(n + 1);
305 const auto functionInput = node.input(0);
306 JLM_ASSERT(is<rvsdg::FunctionType>(functionInput->Type()));
307 return *functionInput;
317 const auto ioState = node.input(node.ninputs() - 2);
329 const auto ioState = node.output(node.noutputs() - 2);
341 const auto memoryState = node.input(node.ninputs() - 1);
342 JLM_ASSERT(is<MemoryStateType>(memoryState->Type()));
353 const auto memoryState = node.output(node.noutputs() - 1);
354 JLM_ASSERT(is<MemoryStateType>(memoryState->Type()));
374 return is<CallEntryMemoryStateMergeOperation>(node) ? node :
nullptr;
398 return is<CallExitMemoryStateSplitOperation>(node) ? node :
nullptr;
422 static std::unique_ptr<CallTypeClassifier>
425 static std::unique_ptr<ThreeAddressCode>
428 std::shared_ptr<const rvsdg::FunctionType> functionType,
429 const std::vector<const Variable *> & arguments)
433 auto op = std::make_unique<CallOperation>(std::move(functionType));
434 std::vector<const Variable *>
operands({
function });
439 static std::vector<rvsdg::Output *>
442 std::shared_ptr<const rvsdg::FunctionType> functionType,
443 const std::vector<rvsdg::Output *> & arguments)
448 static std::vector<rvsdg::Output *>
451 std::unique_ptr<CallOperation> callOperation,
452 const std::vector<rvsdg::Output *> &
operands)
460 std::unique_ptr<CallOperation> callOperation,
461 const std::vector<rvsdg::Output *> &
operands)
471 std::shared_ptr<const rvsdg::FunctionType> functionType,
472 const std::vector<rvsdg::Output *> & arguments)
476 auto callOperation = std::make_unique<CallOperation>(std::move(functionType));
484 static inline std::vector<std::shared_ptr<const rvsdg::Type>>
487 std::vector<std::shared_ptr<const rvsdg::Type>> types({ functionType });
488 for (
auto & argumentType : functionType->Arguments())
489 types.emplace_back(argumentType);
497 if (!is<rvsdg::FunctionType>(
type))
507 throw util::Error(
"Expected at least three argument types.");
509 auto memoryStateArgumentIndex = functionType.
NumArguments() - 1;
510 auto iOStateArgumentIndex = functionType.
NumArguments() - 2;
512 if (!is<MemoryStateType>(functionType.
ArgumentType(memoryStateArgumentIndex)))
515 if (!is<IOStateType>(functionType.
ArgumentType(iOStateArgumentIndex)))
522 throw util::Error(
"Expected at least three result types.");
524 auto memoryStateResultIndex = functionType.
NumResults() - 1;
525 auto iOStateResultIndex = functionType.
NumResults() - 2;
527 if (!is<MemoryStateType>(functionType.
ResultType(memoryStateResultIndex)))
530 if (!is<IOStateType>(functionType.
ResultType(iOStateResultIndex)))
534 CheckArgumentTypes(functionType);
535 CheckResultTypes(functionType);
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 std::unique_ptr< CallTypeClassifier > ClassifyCall(const rvsdg::SimpleNode &callNode)
Classifies a call node.
static rvsdg::Input & GetMemoryStateInput(const rvsdg::Node &node) 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 std::vector< rvsdg::Output * > Create(rvsdg::Region ®ion, std::unique_ptr< CallOperation > callOperation, const std::vector< rvsdg::Output * > &operands)
static rvsdg::Output & GetIOStateOutput(const rvsdg::Node &node) noexcept
static void CheckFunctionType(const rvsdg::FunctionType &functionType)
bool operator==(const Operation &other) const noexcept override
static rvsdg::Output & GetMemoryStateOutput(const rvsdg::Node &node) noexcept
std::string debug_string() const override
static rvsdg::SimpleNode & CreateNode(rvsdg::Output *function, std::shared_ptr< const rvsdg::FunctionType > functionType, const std::vector< rvsdg::Output * > &arguments)
CallOperation(std::shared_ptr< const rvsdg::FunctionType > functionType)
static rvsdg::SimpleNode * tryGetMemoryStateEntryMerge(const rvsdg::Node &callNode) noexcept
static std::unique_ptr< ThreeAddressCode > create(const Variable *function, std::shared_ptr< const rvsdg::FunctionType > functionType, const std::vector< const Variable * > &arguments)
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::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)