diff --git a/jlm/rvsdg/simple-node.cpp b/jlm/rvsdg/simple-node.cpp index 457d91689..0596cfc7e 100644 --- a/jlm/rvsdg/simple-node.cpp +++ b/jlm/rvsdg/simple-node.cpp @@ -67,6 +67,32 @@ SimpleNode::SimpleNode( on_node_create(this); } +SimpleNode::SimpleNode( + rvsdg::Region & region, + std::unique_ptr operation, + const std::vector & operands) + : Node(std::move(operation), ®ion) +{ + 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(this, operands[n], SimpleNode::GetOperation().argument(n))); + } + + for (size_t n = 0; n < SimpleNode::GetOperation().nresults(); n++) + add_output(std::make_unique(this, SimpleNode::GetOperation().result(n))); + + on_node_create(this); +} + const SimpleOperation & SimpleNode::GetOperation() const noexcept { diff --git a/jlm/rvsdg/simple-node.hpp b/jlm/rvsdg/simple-node.hpp index 606e3e1c2..e13fc28b0 100644 --- a/jlm/rvsdg/simple-node.hpp +++ b/jlm/rvsdg/simple-node.hpp @@ -29,6 +29,11 @@ class SimpleNode : public Node const SimpleOperation & op, const std::vector & operands); + SimpleNode( + rvsdg::Region & region, + std::unique_ptr operation, + const std::vector & operands); + public: jlm::rvsdg::simple_input * input(size_t index) const noexcept; @@ -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 operation, + const std::vector & operands) + { + return *new SimpleNode(region, std::move(operation), operands); + } + static inline std::vector create_normalized( rvsdg::Region * region, @@ -120,6 +134,91 @@ SimpleNode::output(size_t index) const noexcept return static_cast(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( + * { ptr }, offsetTypes, pointeeTypes).outputs(0); + * \endcode + */ +template +SimpleNode & +CreateOpNode(const std::vector & operands, OperatorArguments... operatorArguments) +{ + JLM_ASSERT(!operands.empty()); + return SimpleNode::Create( + *operands[0]->region(), + std::make_unique(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(region, 42).outputs(0); + * \endcode + */ +template +SimpleNode & +CreateOpNode(Region & region, OperatorArguments... operatorArguments) +{ + return SimpleNode::Create( + region, + std::make_unique(std::move(operatorArguments)...), + {}); +} + } #endif