Jlm
Loading...
Searching...
No Matches
node.hpp
Go to the documentation of this file.
1/*
2 * Copyright 2010 2011 2012 2014 Helge Bahmann <hcb@chaoticmind.net>
3 * Copyright 2011 2012 2013 2014 2015 2016 Nico Reißmann <nico.reissmann@gmail.com>
4 * See COPYING for terms of redistribution.
5 */
6
7#ifndef JLM_RVSDG_NODE_HPP
8#define JLM_RVSDG_NODE_HPP
9
11#include <jlm/util/common.hpp>
12#include <jlm/util/HashSet.hpp>
16
17#include <cstdint>
18#include <utility>
19#include <variant>
20
21namespace jlm::rvsdg
22{
23
24class Graph;
25class Output;
26class SubstitutionMap;
27
28class Input
29{
30 friend class Node;
31 friend class Region;
32
33protected:
34 Input(Node & owner, Output & origin, std::shared_ptr<const rvsdg::Type> type);
35
36 Input(Region & owner, Output & origin, std::shared_ptr<const rvsdg::Type> type);
37
38public:
39 virtual ~Input() noexcept;
40
42
44
45 Input &
47
48 Input &
50
51 size_t
53 {
54 return index_;
55 }
56
57 Output *
59 {
60 return origin_;
61 }
62
63 void
65
66 [[nodiscard]] const std::shared_ptr<const rvsdg::Type> &
68 {
69 return Type_;
70 }
71
72 [[nodiscard]] Region *
74
75 virtual std::string
77
78 [[nodiscard]] std::variant<Node *, Region *>
80 {
81 return Owner_;
82 }
83
85 {
86 public:
87 using iterator_category = std::forward_iterator_tag;
89 using difference_type = std::ptrdiff_t;
90 using pointer = Input *;
91 using reference = Input &;
92
93 constexpr explicit Iterator(Input * input)
94 : Input_(input)
95 {}
96
97 [[nodiscard]] Input *
99 {
100 return Input_;
101 }
102
103 Input &
105 {
106 JLM_ASSERT(Input_ != nullptr);
107 return *Input_;
108 }
109
110 Input *
112 {
113 return Input_;
114 }
115
116 Iterator &
118 {
120 return *this;
121 }
122
125 {
126 Iterator tmp = *this;
127 ++*this;
128 return tmp;
129 }
130
131 bool
132 operator==(const Iterator & other) const
133 {
134 return Input_ == other.Input_;
135 }
136
137 bool
138 operator!=(const Iterator & other) const
139 {
140 return !operator==(other);
141 }
142
143 private:
144 [[nodiscard]] Input *
145 ComputeNext() const;
146
148 };
149
151 {
152 public:
153 using iterator_category = std::forward_iterator_tag;
154 using value_type = const Input;
155 using difference_type = std::ptrdiff_t;
156 using pointer = const Input *;
157 using reference = const Input &;
158
159 constexpr explicit ConstIterator(const Input * input)
160 : Input_(input)
161 {}
162
163 [[nodiscard]] const Input *
165 {
166 return Input_;
167 }
168
169 const Input &
171 {
172 JLM_ASSERT(Input_ != nullptr);
173 return *Input_;
174 }
175
176 const Input *
178 {
179 return Input_;
180 }
181
184 {
186 return *this;
187 }
188
191 {
192 ConstIterator tmp = *this;
193 ++*this;
194 return tmp;
195 }
196
197 bool
199 {
200 return Input_ == other.Input_;
201 }
202
203 bool
205 {
206 return !operator==(other);
207 }
208
209 private:
210 [[nodiscard]] Input *
211 ComputeNext() const;
212
213 const Input * Input_;
214 };
215
216private:
217 static void
219 const Region & region,
220 const Output & origin,
221 const std::shared_ptr<const rvsdg::Type> & type);
222
223 size_t index_;
225 std::variant<Node *, Region *> Owner_;
226 std::shared_ptr<const rvsdg::Type> Type_;
230
231 friend class Output;
232};
233
234template<class T>
235static inline bool
236is(const jlm::rvsdg::Input & input) noexcept
237{
238 static_assert(
239 std::is_base_of<jlm::rvsdg::Input, T>::value,
240 "Template parameter T must be derived from jlm::rvsdg::input.");
241
242 return dynamic_cast<const T *>(&input) != nullptr;
243}
244
246{
247 friend Input;
248 friend class Node;
249 friend class Region;
250
251protected:
252 Output(Node & owner, std::shared_ptr<const rvsdg::Type> type);
253
254 Output(Region * owner, std::shared_ptr<const rvsdg::Type> type);
255
256public:
260
261 virtual ~Output() noexcept;
262
264
266
267 Output &
269
270 Output &
272
273 size_t
275 {
276 return index_;
277 }
278
279 size_t
281 {
282 return NumUsers_;
283 }
284
294 [[nodiscard]] bool
296 {
297 return NumUsers_ == 0;
298 }
299
300 inline void
302 {
303 if (this == new_origin)
304 return;
305
306 while (!Users_.empty())
307 Users_.begin()->divert_to(new_origin);
308 }
309
319 template<typename F>
320 size_t
322 {
323 if (this == &newOrigin)
324 return 0;
325
327 for (auto & user : Users_)
328 {
329 if (match(user))
331 }
332
333 for (auto & user : matchedUsers.Items())
334 {
335 user->divert_to(&newOrigin);
336 }
337
338 return matchedUsers.Size();
339 }
340
348 {
349 JLM_ASSERT(NumUsers_ == 1);
350 return *Users_.begin();
351 }
352
355 {
356 return UsersRange(Users_.begin(), Users_.end());
357 }
358
360 Users() const
361 {
363 }
364
365 [[nodiscard]] const std::shared_ptr<const rvsdg::Type> &
367 {
368 return Type_;
369 }
370
373
374 virtual std::string
376
377 [[nodiscard]] std::variant<Node *, Region *>
379 {
380 return Owner_;
381 }
382
384 {
385 public:
386 using iterator_category = std::forward_iterator_tag;
388 using difference_type = std::ptrdiff_t;
389 using pointer = Output *;
390 using reference = Output &;
391
392 constexpr explicit Iterator(Output * output)
393 : Output_(output)
394 {}
395
396 [[nodiscard]] Output *
398 {
399 return Output_;
400 }
401
402 Output &
404 {
405 JLM_ASSERT(Output_ != nullptr);
406 return *Output_;
407 }
408
409 Output *
411 {
412 return Output_;
413 }
414
415 Iterator &
417 {
419 return *this;
420 }
421
424 {
425 Iterator tmp = *this;
426 ++*this;
427 return tmp;
428 }
429
430 bool
431 operator==(const Iterator & other) const
432 {
433 return Output_ == other.Output_;
434 }
435
436 bool
437 operator!=(const Iterator & other) const
438 {
439 return !operator==(other);
440 }
441
442 private:
443 [[nodiscard]] Output *
444 ComputeNext() const;
445
447 };
448
450 {
451 public:
452 using iterator_category = std::forward_iterator_tag;
453 using value_type = const Output;
454 using difference_type = std::ptrdiff_t;
455 using pointer = const Output *;
456 using reference = const Output &;
457
458 constexpr explicit ConstIterator(const Output * output)
459 : Output_(output)
460 {}
461
462 const Output *
464 {
465 return Output_;
466 }
467
468 const Output &
469 operator*() const
470 {
471 JLM_ASSERT(Output_ != nullptr);
472 return *Output_;
473 }
474
475 const Output *
477 {
478 return Output_;
479 }
480
483 {
485 return *this;
486 }
487
490 {
491 const ConstIterator tmp = *this;
492 ++*this;
493 return tmp;
494 }
495
496 bool
498 {
499 return Output_ == other.Output_;
500 }
501
502 bool
504 {
505 return !operator==(other);
506 }
507
508 private:
509 [[nodiscard]] Output *
510 ComputeNext() const;
511
513 };
514
515private:
516 void
518
519 void
521
522 size_t index_;
523 std::variant<Node *, Region *> Owner_;
524 std::shared_ptr<const rvsdg::Type> Type_;
526 std::size_t NumUsers_ = 0;
527};
528
540Output &
541RouteToRegion(Output & output, Region & region);
542
543template<class T>
544static inline bool
545is(const jlm::rvsdg::Output * output) noexcept
546{
547 static_assert(
548 std::is_base_of<jlm::rvsdg::Output, T>::value,
549 "Template parameter T must be derived from jlm::rvsdg::output.");
550
551 return dynamic_cast<const T *>(output) != nullptr;
552}
553
554class NodeInput : public Input
555{
556public:
557 NodeInput(Output * origin, Node * node, std::shared_ptr<const rvsdg::Type> type);
558
559 [[nodiscard]] Node *
561 {
562 return std::get<Node *>(GetOwner());
563 }
564};
565
566class NodeOutput : public Output
567{
568public:
569 NodeOutput(Node * node, std::shared_ptr<const rvsdg::Type> type);
570
571 [[nodiscard]] Node *
573 {
574 return std::get<Node *>(GetOwner());
575 }
576};
577
578/* node class */
579
580class Node
581{
582public:
583 using Id = uint64_t;
584
589
590 virtual ~Node();
591
592 explicit Node(Region * region);
593
599 [[nodiscard]] Id
601 {
602 return Id_;
603 }
604
605 [[nodiscard]] virtual const Operation &
607
608 inline size_t
610 {
611 return inputs_.size();
612 }
613
614 NodeInput *
615 input(size_t index) const noexcept
616 {
617 JLM_ASSERT(index < ninputs());
618 return inputs_[index].get();
619 }
620
623 {
624 if (ninputs() == 0)
625 {
626 return { Input::Iterator(nullptr), Input::Iterator(nullptr) };
627 }
628
629 return { Input::Iterator(input(0)), Input::Iterator(nullptr) };
630 }
631
634 {
635 if (ninputs() == 0)
636 {
637 return { Input::ConstIterator(nullptr), Input::ConstIterator(nullptr) };
638 }
639
640 return { Input::ConstIterator(input(0)), Input::ConstIterator(nullptr) };
641 }
642
643 inline size_t
645 {
646 return outputs_.size();
647 }
648
649 NodeOutput *
650 output(size_t index) const noexcept
651 {
652 JLM_ASSERT(index < noutputs());
653 return outputs_[index].get();
654 }
655
658 {
659 if (noutputs() == 0)
660 {
661 return { Output::Iterator(nullptr), Output::Iterator(nullptr) };
662 }
663
664 return { Output::Iterator(output(0)), Output::Iterator(nullptr) };
665 }
666
669 {
670 if (noutputs() == 0)
671 {
672 return { Output::ConstIterator(nullptr), Output::ConstIterator(nullptr) };
673 }
674
675 return { Output::ConstIterator(output(0)), Output::ConstIterator(nullptr) };
676 }
677
687 [[nodiscard]] bool
689 {
690 return numSuccessors_ == 0;
691 }
692
693 [[nodiscard]] std::size_t
695 {
696 return numSuccessors_;
697 }
698
699 virtual std::string
700 DebugString() const = 0;
701
702protected:
714 NodeInput *
715 addInput(std::unique_ptr<NodeInput> input, bool notifyRegion);
716
717 // FIXME: I really would not like to be RemoveInputs() to be public
718public:
727 size_t
728 RemoveInputs(const util::HashSet<size_t> & indices);
729
730protected:
731 NodeOutput *
732 addOutput(std::unique_ptr<NodeOutput> output)
733 {
734 if (output->node() != this)
735 throw std::logic_error("Output does not belong to this node!");
737 outputs_.push_back(std::move(output));
738 return this->output(noutputs() - 1);
739 }
740
741 // FIXME: I really would not like to be RemoveOutputs() to be public
742public:
754 size_t
755 RemoveOutputs(const util::HashSet<size_t> & indices);
756
757 [[nodiscard]] Graph *
759
760 [[nodiscard]] rvsdg::Region *
762 {
763 return region_;
764 }
765
766 virtual Node *
767 copy(rvsdg::Region * region, const std::vector<jlm::rvsdg::Output *> & operands) const;
768
785 virtual Node *
787
788private:
790
792
794
795public:
798
801
804
805private:
808 std::vector<std::unique_ptr<NodeInput>> inputs_;
809 std::vector<std::unique_ptr<NodeOutput>> outputs_;
810 std::size_t numSuccessors_ = 0;
811
812 friend class Output;
813};
814
827template<class OperationType>
828inline bool
829is(const Node * node) noexcept
830{
831 if (!node)
832 return false;
833
834 return is<OperationType>(node->GetOperation());
835}
836
843template<typename TOperation>
844[[nodiscard]] const TOperation *
845tryGetOperation(const Node & node) noexcept
846{
847 return dynamic_cast<const TOperation *>(&node.GetOperation());
848}
849
870template<typename NodeType>
871inline NodeType *
872TryGetOwnerNode(const rvsdg::Input & input) noexcept
873{
874 auto owner = input.GetOwner();
875 if (const auto node = std::get_if<Node *>(&owner))
876 {
877 return dynamic_cast<NodeType *>(*node);
878 }
879 else
880 {
881 return nullptr;
882 }
883}
884
905template<typename NodeType>
906inline NodeType *
907TryGetOwnerNode(const rvsdg::Output & output) noexcept
908{
909 auto owner = output.GetOwner();
910 if (const auto node = std::get_if<Node *>(&owner))
911 {
912 return dynamic_cast<NodeType *>(*node);
913 }
914 else
915 {
916 return nullptr;
917 }
918}
919
938template<typename NodeType>
939inline NodeType &
941{
942 auto node = TryGetOwnerNode<NodeType>(input);
943 if (!node)
944 {
945 throw std::logic_error(std::string("expected node of type ") + typeid(NodeType).name());
946 }
947 return *node;
948}
949
968template<typename NodeType>
969inline NodeType &
971{
972 auto node = TryGetOwnerNode<NodeType>(output);
973 if (!node)
974 {
975 throw std::logic_error(std::string("expected node of type ") + typeid(NodeType).name());
976 }
977 return *node;
978}
979
993template<typename OperationType>
994bool
995IsOwnerNodeOperation(const rvsdg::Input & input) noexcept
996{
998}
999
1013template<typename OperationType>
1014bool
1015IsOwnerNodeOperation(const rvsdg::Output & output) noexcept
1016{
1018}
1019
1020inline Region *
1021TryGetOwnerRegion(const rvsdg::Input & input) noexcept
1022{
1023 auto owner = input.GetOwner();
1024 if (auto region = std::get_if<Region *>(&owner))
1025 {
1026 return *region;
1027 }
1028 else
1029 {
1030 return nullptr;
1031 }
1032}
1033
1034inline Region *
1035TryGetOwnerRegion(const rvsdg::Output & output) noexcept
1036{
1037 auto owner = output.GetOwner();
1038 if (auto region = std::get_if<Region *>(&owner))
1039 {
1040 return *region;
1041 }
1042 else
1043 {
1044 return nullptr;
1045 }
1046}
1047
1048static inline std::vector<jlm::rvsdg::Output *>
1049operands(const Node * node)
1050{
1051 std::vector<jlm::rvsdg::Output *> operands;
1052 for (size_t n = 0; n < node->ninputs(); n++)
1053 operands.push_back(node->input(n)->origin());
1054 return operands;
1055}
1056
1057static inline std::vector<jlm::rvsdg::Output *>
1058outputs(const Node * node)
1059{
1060 std::vector<jlm::rvsdg::Output *> outputs;
1061 for (size_t n = 0; n < node->noutputs(); n++)
1062 outputs.push_back(node->output(n));
1063 return outputs;
1064}
1065
1076static inline std::vector<Output *>
1077Outputs(const Node & node, const size_t startIdx, const size_t size)
1078{
1079 JLM_ASSERT(startIdx + size <= node.noutputs());
1080
1081 std::vector<Output *> outputs;
1082 for (size_t n = startIdx; n < startIdx + size; n++)
1083 outputs.push_back(node.output(n));
1084
1085 JLM_ASSERT(outputs.size() == size);
1086 return outputs;
1087}
1088
1089static inline void
1090divert_users(Node * node, const std::vector<Output *> & outputs)
1091{
1092 JLM_ASSERT(node->noutputs() == outputs.size());
1093
1094 for (size_t n = 0; n < outputs.size(); n++)
1095 node->output(n)->divert_users(outputs[n]);
1096}
1097
1098}
1099
1100#endif
ConstIterator & operator++()
Definition node.hpp:183
const Input * GetInput() const noexcept
Definition node.hpp:164
Input * ComputeNext() const
Definition node.cpp:128
constexpr ConstIterator(const Input *input)
Definition node.hpp:159
ConstIterator operator++(int)
Definition node.hpp:190
std::ptrdiff_t difference_type
Definition node.hpp:155
bool operator!=(const ConstIterator &other) const
Definition node.hpp:204
const Input * operator->() const
Definition node.hpp:177
bool operator==(const ConstIterator &other) const
Definition node.hpp:198
std::forward_iterator_tag iterator_category
Definition node.hpp:153
std::ptrdiff_t difference_type
Definition node.hpp:89
Iterator operator++(int)
Definition node.hpp:124
Input * GetInput() const noexcept
Definition node.hpp:98
std::forward_iterator_tag iterator_category
Definition node.hpp:87
Iterator & operator++()
Definition node.hpp:117
bool operator==(const Iterator &other) const
Definition node.hpp:132
Input * operator->() const
Definition node.hpp:111
bool operator!=(const Iterator &other) const
Definition node.hpp:138
Input * ComputeNext() const
Definition node.cpp:122
constexpr Iterator(Input *input)
Definition node.hpp:93
std::variant< Node *, Region * > Owner_
Definition node.hpp:225
void divert_to(Output *new_origin)
Definition node.cpp:64
jlm::util::IntrusiveList< Input, UsersListAccessor > UsersList
Definition node.hpp:229
std::shared_ptr< const rvsdg::Type > Type_
Definition node.hpp:226
size_t index() const noexcept
Definition node.hpp:52
jlm::rvsdg::Output * origin_
Definition node.hpp:224
virtual std::string debug_string() const
Definition node.cpp:58
std::variant< Node *, Region * > GetOwner() const noexcept
Definition node.hpp:79
Output * origin() const noexcept
Definition node.hpp:58
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
Definition node.hpp:67
Region * region() const noexcept
Definition node.cpp:83
virtual ~Input() noexcept
Definition node.cpp:19
static void CheckTypes(const Region &region, const Output &origin, const std::shared_ptr< const rvsdg::Type > &type)
Definition node.cpp:25
jlm::util::IntrusiveListAnchor< Input > UsersList_
Definition node.hpp:227
Node * node() const noexcept
Definition node.hpp:560
Node * node() const noexcept
Definition node.hpp:572
Graph * graph() const noexcept
Definition node.cpp:282
NodeInput * input(size_t index) const noexcept
Definition node.hpp:615
std::size_t numSuccessors() const noexcept
Definition node.hpp:694
util::IntrusiveListAnchor< Node > region_top_node_list_anchor_
Definition node.hpp:791
NodeOutput * output(size_t index) const noexcept
Definition node.hpp:650
uint64_t Id
Definition node.hpp:583
virtual Node * copy(rvsdg::Region *region, SubstitutionMap &smap) const =0
Copy a node with substitutions.
Region * region_
Definition node.hpp:807
util::IteratorRange< Input::ConstIterator > InputConstIteratorRange
Definition node.hpp:586
Id GetNodeId() const noexcept
Definition node.hpp:600
virtual std::string DebugString() const =0
util::IteratorRange< Input::Iterator > InputIteratorRange
Definition node.hpp:585
virtual ~Node()
Definition node.cpp:265
OutputIteratorRange Outputs() noexcept
Definition node.hpp:657
bool IsDead() const noexcept
Determines whether the node is dead.
Definition node.hpp:688
virtual const Operation & GetOperation() const noexcept=0
std::vector< std::unique_ptr< NodeInput > > inputs_
Definition node.hpp:808
std::vector< std::unique_ptr< NodeOutput > > outputs_
Definition node.hpp:809
util::IteratorRange< Output::ConstIterator > OutputConstIteratorRange
Definition node.hpp:588
util::IntrusiveListAccessor< Node, &Node::region_top_node_list_anchor_ > region_top_node_list_accessor
Definition node.hpp:800
size_t RemoveInputs(const util::HashSet< size_t > &indices)
Definition node.cpp:306
InputConstIteratorRange Inputs() const noexcept
Definition node.hpp:633
rvsdg::Region * region() const noexcept
Definition node.hpp:761
util::IntrusiveListAccessor< Node, &Node::region_bottom_node_list_anchor_ > region_bottom_node_list_accessor
Definition node.hpp:803
InputIteratorRange Inputs() noexcept
Definition node.hpp:622
size_t ninputs() const noexcept
Definition node.hpp:609
util::IteratorRange< Output::Iterator > OutputIteratorRange
Definition node.hpp:587
util::IntrusiveListAnchor< Node > region_node_list_anchor_
Definition node.hpp:789
NodeOutput * addOutput(std::unique_ptr< NodeOutput > output)
Definition node.hpp:732
util::IntrusiveListAccessor< Node, &Node::region_node_list_anchor_ > region_node_list_accessor
Definition node.hpp:797
size_t noutputs() const noexcept
Definition node.hpp:644
OutputConstIteratorRange Outputs() const noexcept
Definition node.hpp:668
util::IntrusiveListAnchor< Node > region_bottom_node_list_anchor_
Definition node.hpp:793
std::size_t numSuccessors_
Definition node.hpp:810
NodeInput * addInput(std::unique_ptr< NodeInput > input, bool notifyRegion)
Definition node.cpp:288
size_t RemoveOutputs(const util::HashSet< size_t > &indices)
Definition node.cpp:342
virtual Node * copy(rvsdg::Region *region, const std::vector< jlm::rvsdg::Output * > &operands) const
Definition node.cpp:369
const Output * GetOutput() const noexcept
Definition node.hpp:463
constexpr ConstIterator(const Output *output)
Definition node.hpp:458
ConstIterator & operator++()
Definition node.hpp:482
bool operator!=(const ConstIterator &other) const
Definition node.hpp:503
Output * ComputeNext() const
Definition node.cpp:240
const Output * operator->() const
Definition node.hpp:476
const Output & operator*() const
Definition node.hpp:469
bool operator==(const ConstIterator &other) const
Definition node.hpp:497
std::forward_iterator_tag iterator_category
Definition node.hpp:452
ConstIterator operator++(int)
Definition node.hpp:489
Iterator operator++(int)
Definition node.hpp:423
constexpr Iterator(Output *output)
Definition node.hpp:392
Output * operator->() const
Definition node.hpp:410
std::ptrdiff_t difference_type
Definition node.hpp:388
bool operator==(const Iterator &other) const
Definition node.hpp:431
std::forward_iterator_tag iterator_category
Definition node.hpp:386
bool operator!=(const Iterator &other) const
Definition node.hpp:437
Output * GetOutput() const noexcept
Definition node.hpp:397
Output * ComputeNext() const
Definition node.cpp:234
std::size_t NumUsers_
Definition node.hpp:526
rvsdg::Input & SingleUser() noexcept
Definition node.hpp:347
jlm::util::IteratorRange< UsersList::ConstIterator > UsersConstRange
Definition node.hpp:259
void add_user(jlm::rvsdg::Input *user)
Definition node.cpp:193
rvsdg::Region * region() const noexcept
Definition node.cpp:151
virtual ~Output() noexcept
Definition node.cpp:133
UsersRange Users()
Definition node.hpp:354
virtual std::string debug_string() const
Definition node.cpp:168
size_t index() const noexcept
Definition node.hpp:274
size_t divertUsersWhere(Output &newOrigin, const F &match)
Definition node.hpp:321
void divert_users(jlm::rvsdg::Output *new_origin)
Definition node.hpp:301
void remove_user(jlm::rvsdg::Input *user)
Definition node.cpp:174
std::variant< Node *, Region * > Owner_
Definition node.hpp:523
std::shared_ptr< const rvsdg::Type > Type_
Definition node.hpp:524
std::variant< Node *, Region * > GetOwner() const noexcept
Definition node.hpp:378
UsersConstRange Users() const
Definition node.hpp:360
UsersList Users_
Definition node.hpp:525
bool IsDead() const noexcept
Definition node.hpp:295
jlm::util::IteratorRange< UsersList::Iterator > UsersRange
Definition node.hpp:258
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
Definition node.hpp:366
size_t nusers() const noexcept
Definition node.hpp:280
Represent acyclic RVSDG subgraphs.
Definition region.hpp:213
bool insert(ItemType item)
Definition HashSet.hpp:210
Iterator end() noexcept
bool empty() const noexcept
ConstIterator cend() const noexcept
ConstIterator cbegin() const noexcept
Iterator begin() noexcept
#define JLM_ASSERT(x)
Definition common.hpp:16
static bool is(const jlm::rvsdg::Input &input) noexcept
Definition node.hpp:236
NodeType & AssertGetOwnerNode(const rvsdg::Input &input)
Asserts that this is an input to a node of specified type.
Definition node.hpp:940
static std::vector< Output * > Outputs(const Node &node, const size_t startIdx, const size_t size)
Definition node.hpp:1077
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
Definition node.hpp:1049
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)
Definition node.hpp:1058
Output & RouteToRegion(Output &output, Region &region)
Definition node.cpp:381
bool IsOwnerNodeOperation(const rvsdg::Input &input) noexcept
Checks if the input belongs to a node of the specified operation type.
Definition node.hpp:995
const TOperation * tryGetOperation(const Node &node) noexcept
Definition node.hpp:845
static void divert_users(Node *node, const std::vector< Output * > &outputs)
Definition node.hpp:1090
Region * TryGetOwnerRegion(const rvsdg::Input &input) noexcept
Definition node.hpp:1021
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872