Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SimpleNode: convenience builder functions #704

Merged
merged 1 commit into from
Jan 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions jlm/rvsdg/simple-node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,32 @@ SimpleNode::SimpleNode(
on_node_create(this);
}

SimpleNode::SimpleNode(
rvsdg::Region & region,
std::unique_ptr<SimpleOperation> operation,
const std::vector<jlm::rvsdg::output *> & operands)
: Node(std::move(operation), &region)
{
if (SimpleNode::GetOperation().narguments() != operands.size())
throw jlm::util::error(jlm::util::strfmt(
"Argument error - expected ",
SimpleNode::GetOperation().narguments(),
", received ",
operands.size(),
" arguments."));

for (size_t n = 0; n < SimpleNode::GetOperation().narguments(); n++)
{
add_input(
std::make_unique<simple_input>(this, operands[n], SimpleNode::GetOperation().argument(n)));
}

for (size_t n = 0; n < SimpleNode::GetOperation().nresults(); n++)
add_output(std::make_unique<simple_output>(this, SimpleNode::GetOperation().result(n)));

on_node_create(this);
}

const SimpleOperation &
SimpleNode::GetOperation() const noexcept
{
Expand Down
99 changes: 99 additions & 0 deletions jlm/rvsdg/simple-node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ class SimpleNode : public Node
const SimpleOperation & op,
const std::vector<jlm::rvsdg::output *> & operands);

SimpleNode(
rvsdg::Region & region,
std::unique_ptr<SimpleOperation> operation,
const std::vector<jlm::rvsdg::output *> & operands);

public:
jlm::rvsdg::simple_input *
input(size_t index) const noexcept;
Expand All @@ -54,6 +59,15 @@ class SimpleNode : public Node
return new SimpleNode(region, op, operands);
}

static inline jlm::rvsdg::SimpleNode &
Create(
rvsdg::Region & region,
std::unique_ptr<SimpleOperation> operation,
const std::vector<jlm::rvsdg::output *> & operands)
{
return *new SimpleNode(region, std::move(operation), operands);
}

static inline std::vector<jlm::rvsdg::output *>
create_normalized(
rvsdg::Region * region,
Expand Down Expand Up @@ -120,6 +134,91 @@ SimpleNode::output(size_t index) const noexcept
return static_cast<simple_output *>(Node::output(index));
}

/**
* \brief Creates a simple node characterized by its operator.
*
* \tparam OperatorType
* The type of operator wrapped by the node.
*
* \tparam OperatorArguments
* Argument types of the operator to be constructed (should be
* implied, just specify the OperatorType).
*
* \param operands
* The operands to the operator (i.e. inputs to the node to be constructed).
*
* \param operatorArguments
* Constructor arguments for the operator to be constructed.
*
* \returns
* Reference to the node constructed.
*
* \pre
* \p operands must be non-empty, must be in the same region, and their
* types must match the operator constructed by this call.
*
* Constructs a new operator of type \p OperatorType using \p operatorArguments
* as constructor arguments. Creates a simple node using the constructed operator
* and the given \p operands as operands to the constructed operator.
*
* Usage example:
* \code
* auto element_ptr = CreateOpNode<GetElementPtrOperation>(
* { ptr }, offsetTypes, pointeeTypes).outputs(0);
* \endcode
*/
template<typename OperatorType, typename... OperatorArguments>
SimpleNode &
CreateOpNode(const std::vector<output *> & operands, OperatorArguments... operatorArguments)
{
JLM_ASSERT(!operands.empty());
return SimpleNode::Create(
*operands[0]->region(),
std::make_unique<OperatorType>(std::move(operatorArguments)...),
operands);
}

/**
* \brief Creates a simple node characterized by its operator.
*
* \tparam OperatorType
* The type of operator wrapped by the node.
*
* \tparam OperatorArguments
* Argument types of the operator to be constructed (should be
* implied, just specify the OperatorType).
*
* \param region
* The region to create the node in.
*
* \param operatorArguments
* Constructor arguments for the operator to be constructed.
*
* \returns
* Reference to the node constructed.
*
* \pre
* The given operator must not take any operands.
*
* Constructs a new operator of type \p OperatorType using \p operatorArguments
* as constructor arguments. Creates a simple node using the constructed operator
* with no operands in the specified region.
*
* Usage example:
* \code
* auto val = CreateOpNode<IntegerConstantOperation>(region, 42).outputs(0);
* \endcode
*/
template<typename OperatorType, typename... OperatorArguments>
SimpleNode &
CreateOpNode(Region & region, OperatorArguments... operatorArguments)
{
return SimpleNode::Create(
region,
std::make_unique<OperatorType>(std::move(operatorArguments)...),
{});
}

}

#endif
Loading