7 #ifndef JLM_RVSDG_NODE_HPP
8 #define JLM_RVSDG_NODE_HPP
26 class SubstitutionMap;
46 operator=(const
Input &) = delete;
66 [[nodiscard]]
const std::shared_ptr<const rvsdg::Type> &
144 [[nodiscard]]
Input *
163 [[nodiscard]]
const Input *
210 [[nodiscard]]
Input *
221 const std::shared_ptr<const rvsdg::Type> &
type);
226 std::shared_ptr<const rvsdg::Type>
Type_;
239 std::is_base_of<jlm::rvsdg::Input, T>::value,
240 "Template parameter T must be derived from jlm::rvsdg::input.");
242 return dynamic_cast<const T *
>(&input) !=
nullptr;
303 if (
this == new_origin)
323 if (
this == &newOrigin)
327 for (
auto & user :
Users_)
330 matchedUsers.
insert(&user);
333 for (
auto & user : matchedUsers.
Items())
335 user->divert_to(&newOrigin);
338 return matchedUsers.
Size();
365 [[nodiscard]]
const std::shared_ptr<const rvsdg::Type> &
524 std::shared_ptr<const rvsdg::Type>
Type_;
548 std::is_base_of<jlm::rvsdg::Output, T>::value,
549 "Template parameter T must be derived from jlm::rvsdg::output.");
551 return dynamic_cast<const T *
>(output) !=
nullptr;
562 return std::get<Node *>(
GetOwner());
574 return std::get<Node *>(
GetOwner());
693 [[nodiscard]] std::size_t
715 addInput(std::unique_ptr<NodeInput>
input,
bool notifyRegion);
735 throw std::logic_error(
"Output does not belong to this node!");
757 [[nodiscard]]
Graph *
758 graph() const noexcept;
760 [[nodiscard]] rvsdg::
Region *
808 std::vector<std::unique_ptr<NodeInput>>
inputs_;
827 template<
class OperationType>
834 return is<OperationType>(node->GetOperation());
843 template<
typename TOperation>
844 [[nodiscard]]
const TOperation *
847 return dynamic_cast<const TOperation *
>(&node.GetOperation());
870 template<
typename NodeType>
874 auto owner = input.GetOwner();
875 if (
const auto node = std::get_if<Node *>(&owner))
877 return dynamic_cast<NodeType *
>(*node);
905 template<
typename NodeType>
909 auto owner = output.GetOwner();
910 if (
const auto node = std::get_if<Node *>(&owner))
912 return dynamic_cast<NodeType *
>(*node);
938 template<
typename NodeType>
942 auto node = TryGetOwnerNode<NodeType>(input);
945 throw std::logic_error(std::string(
"expected node of type ") +
typeid(NodeType).name());
968 template<
typename NodeType>
972 auto node = TryGetOwnerNode<NodeType>(output);
975 throw std::logic_error(std::string(
"expected node of type ") +
typeid(NodeType).name());
993 template<
typename OperationType>
997 return is<OperationType>(TryGetOwnerNode<Node>(input));
1013 template<
typename OperationType>
1017 return is<OperationType>(TryGetOwnerNode<Node>(output));
1023 auto owner = input.GetOwner();
1024 if (
auto region = std::get_if<Region *>(&owner))
1037 auto owner = output.GetOwner();
1038 if (
auto region = std::get_if<Region *>(&owner))
1048 static inline std::vector<jlm::rvsdg::Output *>
1051 std::vector<jlm::rvsdg::Output *>
operands;
1052 for (
size_t n = 0; n < node->
ninputs(); n++)
1057 static inline std::vector<jlm::rvsdg::Output *>
1060 std::vector<jlm::rvsdg::Output *>
outputs;
1061 for (
size_t n = 0; n < node->
noutputs(); n++)
1076 static inline std::vector<Output *>
1081 std::vector<Output *>
outputs;
1082 for (
size_t n = startIdx; n < startIdx + size; n++)
1094 for (
size_t n = 0; n <
outputs.size(); n++)
Node * node() const noexcept
NodeOutput(Node *node, std::shared_ptr< const rvsdg::Type > type)
Graph * graph() const noexcept
std::size_t numSuccessors() const noexcept
util::IntrusiveListAnchor< Node > region_top_node_list_anchor_
virtual const Operation & GetOperation() const noexcept=0
util::IteratorRange< Input::ConstIterator > InputConstIteratorRange
Id GetNodeId() const noexcept
virtual std::string DebugString() const =0
util::IteratorRange< Input::Iterator > InputIteratorRange
NodeOutput * addOutput(std::unique_ptr< NodeOutput > output)
OutputIteratorRange Outputs() noexcept
bool IsDead() const noexcept
Determines whether the node is dead.
rvsdg::Region * region() const noexcept
std::vector< std::unique_ptr< NodeInput > > inputs_
std::vector< std::unique_ptr< NodeOutput > > outputs_
util::IteratorRange< Output::ConstIterator > OutputConstIteratorRange
util::IntrusiveListAccessor< Node, &Node::region_top_node_list_anchor_ > region_top_node_list_accessor
size_t RemoveInputs(const util::HashSet< size_t > &indices)
InputConstIteratorRange Inputs() const noexcept
NodeInput * input(size_t index) const noexcept
util::IntrusiveListAccessor< Node, &Node::region_bottom_node_list_anchor_ > region_bottom_node_list_accessor
InputIteratorRange Inputs() noexcept
NodeOutput * output(size_t index) const noexcept
size_t ninputs() const noexcept
util::IteratorRange< Output::Iterator > OutputIteratorRange
util::IntrusiveListAnchor< Node > region_node_list_anchor_
util::IntrusiveListAccessor< Node, &Node::region_node_list_anchor_ > region_node_list_accessor
size_t noutputs() const noexcept
virtual Node * copy(rvsdg::Region *region, SubstitutionMap &smap) const =0
Copy a node with substitutions.
OutputConstIteratorRange Outputs() const noexcept
util::IntrusiveListAnchor< Node > region_bottom_node_list_anchor_
std::size_t numSuccessors_
NodeInput * addInput(std::unique_ptr< NodeInput > input, bool notifyRegion)
size_t RemoveOutputs(const util::HashSet< size_t > &indices)
virtual Node * copy(rvsdg::Region *region, const std::vector< jlm::rvsdg::Output * > &operands) const
const Output * operator->() const
const Output * GetOutput() const noexcept
constexpr ConstIterator(const Output *output)
bool operator!=(const ConstIterator &other) const
Output * ComputeNext() const
ConstIterator & operator++()
std::ptrdiff_t difference_type
bool operator==(const ConstIterator &other) const
std::forward_iterator_tag iterator_category
const Output & operator*() const
ConstIterator operator++(int)
constexpr Iterator(Output *output)
std::ptrdiff_t difference_type
bool operator==(const Iterator &other) const
Output * GetOutput() const noexcept
std::forward_iterator_tag iterator_category
bool operator!=(const Iterator &other) const
Output * ComputeNext() const
Output * operator->() const
rvsdg::Input & SingleUser() noexcept
jlm::util::IteratorRange< UsersList::ConstIterator > UsersConstRange
void add_user(jlm::rvsdg::Input *user)
rvsdg::Region * region() const noexcept
std::variant< Node *, Region * > GetOwner() const noexcept
virtual ~Output() noexcept
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
virtual std::string debug_string() const
size_t index() const noexcept
size_t divertUsersWhere(Output &newOrigin, const F &match)
void divert_users(jlm::rvsdg::Output *new_origin)
void remove_user(jlm::rvsdg::Input *user)
std::variant< Node *, Region * > Owner_
std::shared_ptr< const rvsdg::Type > Type_
UsersConstRange Users() const
bool IsDead() const noexcept
jlm::util::IteratorRange< UsersList::Iterator > UsersRange
Output(Node &owner, std::shared_ptr< const rvsdg::Type > type)
size_t nusers() const noexcept
Represent acyclic RVSDG subgraphs.
bool insert(ItemType item)
std::size_t Size() const noexcept
IteratorRange< ItemConstIterator > Items() const noexcept
bool empty() const noexcept
ConstIterator cend() const noexcept
ConstIterator cbegin() const noexcept
Iterator begin() noexcept
static bool is(const jlm::rvsdg::Input &input) noexcept
NodeType & AssertGetOwnerNode(const rvsdg::Input &input)
Asserts that this is an input to a node of specified type.
static std::vector< Output * > Outputs(const Node &node, const size_t startIdx, const size_t size)
static std::string type(const Node *n)
Output & RouteToRegion(Output &output, Region ®ion)
bool IsOwnerNodeOperation(const rvsdg::Input &input) noexcept
Checks if the input belongs to a node of the specified operation type.
jlm::rvsdg::Output * match(size_t nbits, const std::unordered_map< uint64_t, uint64_t > &mapping, uint64_t default_alternative, size_t nalternatives, jlm::rvsdg::Output *operand)
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
static void divert_users(Node *node, const std::vector< Output * > &outputs)
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)
const TOperation * tryGetOperation(const Node &node) noexcept
Region * TryGetOwnerRegion(const rvsdg::Input &input) noexcept