Skip to content

Commit

Permalink
SimpleNode: convenience builder functions
Browse files Browse the repository at this point in the history
Add constructor as well as helper function to create simple and its
operator in a single call. Allow to move the created operator in (instead of
copying it).
  • Loading branch information
caleridas committed Jan 4, 2025
1 parent a145d70 commit a8a507a
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 0 deletions.
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

0 comments on commit a8a507a

Please sign in to comment.