Jlm
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 
10 #include <jlm/rvsdg/operation.hpp>
11 #include <jlm/util/common.hpp>
12 #include <jlm/util/HashSet.hpp>
16 
17 #include <cstdint>
18 #include <utility>
19 #include <variant>
20 
21 namespace jlm::rvsdg
22 {
23 
24 class Graph;
25 class Output;
26 class SubstitutionMap;
27 
28 class Input
29 {
30  friend class Node;
31  friend class Region;
32 
33 protected:
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 
38 public:
39  virtual ~Input() noexcept;
40 
41  Input(const Input &) = delete;
42 
43  Input(Input &&) = delete;
44 
45  Input &
46  operator=(const Input &) = delete;
47 
48  Input &
49  operator=(Input &&) = delete;
50 
51  size_t
52  index() const noexcept
53  {
54  return index_;
55  }
56 
57  Output *
58  origin() const noexcept
59  {
60  return origin_;
61  }
62 
63  void
64  divert_to(Output * new_origin);
65 
66  [[nodiscard]] const std::shared_ptr<const rvsdg::Type> &
67  Type() const noexcept
68  {
69  return Type_;
70  }
71 
72  [[nodiscard]] Region *
73  region() const noexcept;
74 
75  virtual std::string
76  debug_string() const;
77 
78  [[nodiscard]] std::variant<Node *, Region *>
79  GetOwner() const noexcept
80  {
81  return Owner_;
82  }
83 
84  class Iterator final
85  {
86  public:
87  using iterator_category = std::forward_iterator_tag;
88  using value_type = Input;
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 *
98  GetInput() const noexcept
99  {
100  return Input_;
101  }
102 
103  Input &
105  {
106  JLM_ASSERT(Input_ != nullptr);
107  return *Input_;
108  }
109 
110  Input *
111  operator->() const
112  {
113  return Input_;
114  }
115 
116  Iterator &
118  {
119  Input_ = ComputeNext();
120  return *this;
121  }
122 
123  Iterator
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 
150  class ConstIterator final
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 *
164  GetInput() const noexcept
165  {
166  return Input_;
167  }
168 
169  const Input &
171  {
172  JLM_ASSERT(Input_ != nullptr);
173  return *Input_;
174  }
175 
176  const Input *
177  operator->() const
178  {
179  return Input_;
180  }
181 
182  ConstIterator &
184  {
185  Input_ = ComputeNext();
186  return *this;
187  }
188 
191  {
192  ConstIterator tmp = *this;
193  ++*this;
194  return tmp;
195  }
196 
197  bool
198  operator==(const ConstIterator & other) const
199  {
200  return Input_ == other.Input_;
201  }
202 
203  bool
204  operator!=(const ConstIterator & other) const
205  {
206  return !operator==(other);
207  }
208 
209  private:
210  [[nodiscard]] Input *
211  ComputeNext() const;
212 
213  const Input * Input_;
214  };
215 
216 private:
217  static void
218  CheckTypes(
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 
234 template<class T>
235 static inline bool
236 is(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 
245 class Output
246 {
247  friend Input;
248  friend class Node;
249  friend class Region;
250 
251 protected:
252  Output(Node & owner, std::shared_ptr<const rvsdg::Type> type);
253 
254  Output(Region * owner, std::shared_ptr<const rvsdg::Type> type);
255 
256 public:
260 
261  virtual ~Output() noexcept;
262 
263  Output(const Output &) = delete;
264 
265  Output(Output &&) = delete;
266 
267  Output &
268  operator=(const Output &) = delete;
269 
270  Output &
271  operator=(Output &&) = delete;
272 
273  size_t
274  index() const noexcept
275  {
276  return index_;
277  }
278 
279  size_t
280  nusers() const noexcept
281  {
282  return NumUsers_;
283  }
284 
294  [[nodiscard]] bool
295  IsDead() const noexcept
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
321  divertUsersWhere(Output & newOrigin, const F & match)
322  {
323  if (this == &newOrigin)
324  return 0;
325 
326  util::HashSet<Input *> matchedUsers;
327  for (auto & user : Users_)
328  {
329  if (match(user))
330  matchedUsers.insert(&user);
331  }
332 
333  for (auto & user : matchedUsers.Items())
334  {
335  user->divert_to(&newOrigin);
336  }
337 
338  return matchedUsers.Size();
339  }
340 
346  [[nodiscard]] rvsdg::Input &
347  SingleUser() noexcept
348  {
349  JLM_ASSERT(NumUsers_ == 1);
350  return *Users_.begin();
351  }
352 
353  UsersRange
355  {
356  return UsersRange(Users_.begin(), Users_.end());
357  }
358 
360  Users() const
361  {
362  return UsersConstRange(Users_.cbegin(), Users_.cend());
363  }
364 
365  [[nodiscard]] const std::shared_ptr<const rvsdg::Type> &
366  Type() const noexcept
367  {
368  return Type_;
369  }
370 
371  [[nodiscard]] rvsdg::Region *
372  region() const noexcept;
373 
374  virtual std::string
375  debug_string() const;
376 
377  [[nodiscard]] std::variant<Node *, Region *>
378  GetOwner() const noexcept
379  {
380  return Owner_;
381  }
382 
383  class Iterator final
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 *
397  GetOutput() const noexcept
398  {
399  return Output_;
400  }
401 
402  Output &
404  {
405  JLM_ASSERT(Output_ != nullptr);
406  return *Output_;
407  }
408 
409  Output *
410  operator->() const
411  {
412  return Output_;
413  }
414 
415  Iterator &
417  {
418  Output_ = ComputeNext();
419  return *this;
420  }
421 
422  Iterator
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 
449  class ConstIterator final
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 *
463  GetOutput() const noexcept
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 *
476  operator->() const
477  {
478  return Output_;
479  }
480 
481  ConstIterator &
483  {
484  Output_ = ComputeNext();
485  return *this;
486  }
487 
490  {
491  const ConstIterator tmp = *this;
492  ++*this;
493  return tmp;
494  }
495 
496  bool
497  operator==(const ConstIterator & other) const
498  {
499  return Output_ == other.Output_;
500  }
501 
502  bool
503  operator!=(const ConstIterator & other) const
504  {
505  return !operator==(other);
506  }
507 
508  private:
509  [[nodiscard]] Output *
510  ComputeNext() const;
511 
512  const Output * Output_;
513  };
514 
515 private:
516  void
518 
519  void
520  add_user(jlm::rvsdg::Input * user);
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 
540 Output &
541 RouteToRegion(Output & output, Region & region);
542 
543 template<class T>
544 static inline bool
545 is(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 
554 class NodeInput : public Input
555 {
556 public:
557  NodeInput(Output * origin, Node * node, std::shared_ptr<const rvsdg::Type> type);
558 
559  [[nodiscard]] Node *
560  node() const noexcept
561  {
562  return std::get<Node *>(GetOwner());
563  }
564 };
565 
566 class NodeOutput : public Output
567 {
568 public:
569  NodeOutput(Node * node, std::shared_ptr<const rvsdg::Type> type);
570 
571  [[nodiscard]] Node *
572  node() const noexcept
573  {
574  return std::get<Node *>(GetOwner());
575  }
576 };
577 
578 /* node class */
579 
580 class Node
581 {
582 public:
583  using Id = uint64_t;
584 
589 
590  virtual ~Node();
591 
592  explicit Node(Region * region);
593 
599  [[nodiscard]] Id
600  GetNodeId() const noexcept
601  {
602  return Id_;
603  }
604 
605  [[nodiscard]] virtual const Operation &
606  GetOperation() const noexcept = 0;
607 
608  inline size_t
609  ninputs() const noexcept
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 
621  [[nodiscard]] InputIteratorRange
622  Inputs() noexcept
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 
632  [[nodiscard]] InputConstIteratorRange
633  Inputs() const noexcept
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
644  noutputs() const noexcept
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 
656  [[nodiscard]] OutputIteratorRange
657  Outputs() noexcept
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 
667  [[nodiscard]] OutputConstIteratorRange
668  Outputs() const noexcept
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
688  IsDead() const noexcept
689  {
690  return numSuccessors_ == 0;
691  }
692 
693  [[nodiscard]] std::size_t
694  numSuccessors() const noexcept
695  {
696  return numSuccessors_;
697  }
698 
699  virtual std::string
700  DebugString() const = 0;
701 
702 protected:
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
718 public:
727  size_t
728  RemoveInputs(const util::HashSet<size_t> & indices);
729 
730 protected:
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!");
736  output->index_ = noutputs();
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
742 public:
754  size_t
755  RemoveOutputs(const util::HashSet<size_t> & indices);
756 
757  [[nodiscard]] Graph *
758  graph() const noexcept;
759 
760  [[nodiscard]] rvsdg::Region *
761  region() const noexcept
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 *
786  copy(rvsdg::Region * region, SubstitutionMap & smap) const = 0;
787 
788 private:
790 
792 
794 
795 public:
798 
801 
804 
805 private:
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 
827 template<class OperationType>
828 inline bool
829 is(const Node * node) noexcept
830 {
831  if (!node)
832  return false;
833 
834  return is<OperationType>(node->GetOperation());
835 }
836 
843 template<typename TOperation>
844 [[nodiscard]] const TOperation *
845 tryGetOperation(const Node & node) noexcept
846 {
847  return dynamic_cast<const TOperation *>(&node.GetOperation());
848 }
849 
870 template<typename NodeType>
871 inline NodeType *
872 TryGetOwnerNode(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 
905 template<typename NodeType>
906 inline NodeType *
907 TryGetOwnerNode(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 
938 template<typename NodeType>
939 inline 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 
968 template<typename NodeType>
969 inline 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 
993 template<typename OperationType>
994 bool
995 IsOwnerNodeOperation(const rvsdg::Input & input) noexcept
996 {
997  return is<OperationType>(TryGetOwnerNode<Node>(input));
998 }
999 
1013 template<typename OperationType>
1014 bool
1015 IsOwnerNodeOperation(const rvsdg::Output & output) noexcept
1016 {
1017  return is<OperationType>(TryGetOwnerNode<Node>(output));
1018 }
1019 
1020 inline Region *
1021 TryGetOwnerRegion(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 
1034 inline Region *
1035 TryGetOwnerRegion(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 
1048 static inline std::vector<jlm::rvsdg::Output *>
1049 operands(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 
1057 static inline std::vector<jlm::rvsdg::Output *>
1058 outputs(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 
1076 static inline std::vector<Output *>
1077 Outputs(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 
1089 static inline void
1090 divert_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
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
bool operator==(const ConstIterator &other) const
Definition: node.hpp:198
const Input & operator*()
Definition: node.hpp:170
const Input * operator->() const
Definition: node.hpp:177
ConstIterator & operator++()
Definition: node.hpp:183
const Input * GetInput() const noexcept
Definition: node.hpp:164
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
Iterator & operator++()
Definition: node.hpp:117
Input * operator->() const
Definition: node.hpp:111
std::forward_iterator_tag iterator_category
Definition: node.hpp:87
bool operator==(const Iterator &other) const
Definition: node.hpp:132
bool operator!=(const Iterator &other) const
Definition: node.hpp:138
Input * ComputeNext() const
Definition: node.cpp:122
Input * GetInput() const noexcept
Definition: node.hpp:98
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
Output * origin() const noexcept
Definition: node.hpp:58
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
Input(Node &owner, Output &origin, std::shared_ptr< const rvsdg::Type > type)
Definition: node.cpp:37
jlm::rvsdg::Output * origin_
Definition: node.hpp:224
virtual std::string debug_string() const
Definition: node.cpp:58
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
Definition: node.hpp:67
std::variant< Node *, Region * > GetOwner() const noexcept
Definition: node.hpp:79
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
size_t index_
Definition: node.hpp:223
jlm::util::IntrusiveListAnchor< Input > UsersList_
Definition: node.hpp:227
NodeInput(Output *origin, Node *node, std::shared_ptr< const rvsdg::Type > type)
Definition: node.cpp:245
Node * node() const noexcept
Definition: node.hpp:560
Node * node() const noexcept
Definition: node.hpp:572
NodeOutput(Node *node, std::shared_ptr< const rvsdg::Type > type)
Definition: node.cpp:252
Graph * graph() const noexcept
Definition: node.cpp:282
Node(Region *region)
Definition: node.cpp:256
std::size_t numSuccessors() const noexcept
Definition: node.hpp:694
util::IntrusiveListAnchor< Node > region_top_node_list_anchor_
Definition: node.hpp:791
virtual const Operation & GetOperation() const noexcept=0
uint64_t Id
Definition: node.hpp:583
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
NodeOutput * addOutput(std::unique_ptr< NodeOutput > output)
Definition: node.hpp:732
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
rvsdg::Region * region() const noexcept
Definition: node.hpp:761
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
NodeInput * input(size_t index) const noexcept
Definition: node.hpp:615
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
NodeOutput * output(size_t index) const noexcept
Definition: node.hpp:650
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
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
virtual Node * copy(rvsdg::Region *region, SubstitutionMap &smap) const =0
Copy a node with substitutions.
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 * operator->() const
Definition: node.hpp:476
const Output * GetOutput() const noexcept
Definition: node.hpp:463
constexpr ConstIterator(const Output *output)
Definition: node.hpp:458
bool operator!=(const ConstIterator &other) const
Definition: node.hpp:503
Output * ComputeNext() const
Definition: node.cpp:240
ConstIterator & operator++()
Definition: node.hpp:482
std::ptrdiff_t difference_type
Definition: node.hpp:454
bool operator==(const ConstIterator &other) const
Definition: node.hpp:497
std::forward_iterator_tag iterator_category
Definition: node.hpp:452
const Output & operator*() const
Definition: node.hpp:469
ConstIterator operator++(int)
Definition: node.hpp:489
Iterator operator++(int)
Definition: node.hpp:423
Iterator & operator++()
Definition: node.hpp:416
constexpr Iterator(Output *output)
Definition: node.hpp:392
std::ptrdiff_t difference_type
Definition: node.hpp:388
bool operator==(const Iterator &other) const
Definition: node.hpp:431
Output * GetOutput() const noexcept
Definition: node.hpp:397
std::forward_iterator_tag iterator_category
Definition: node.hpp:386
bool operator!=(const Iterator &other) const
Definition: node.hpp:437
Output * ComputeNext() const
Definition: node.cpp:234
Output * operator->() const
Definition: node.hpp:410
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
std::variant< Node *, Region * > GetOwner() const noexcept
Definition: node.hpp:378
virtual ~Output() noexcept
Definition: node.cpp:133
UsersRange Users()
Definition: node.hpp:354
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
Definition: node.hpp:366
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
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
Output(Node &owner, std::shared_ptr< const rvsdg::Type > type)
Definition: node.cpp:138
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
std::size_t Size() const noexcept
Definition: HashSet.hpp:187
IteratorRange< ItemConstIterator > Items() const noexcept
Definition: HashSet.hpp:223
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::string type(const Node *n)
Definition: view.cpp:255
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
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)
Definition: control.cpp:179
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition: node.hpp:872
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
Definition: node.hpp:1049
static void divert_users(Node *node, const std::vector< Output * > &outputs)
Definition: node.hpp:1090
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)
Definition: node.hpp:1058
const TOperation * tryGetOperation(const Node &node) noexcept
Definition: node.hpp:845
Region * TryGetOwnerRegion(const rvsdg::Input &input) noexcept
Definition: node.hpp:1021