Jlm
structural-node.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2016 Nico Reißmann <nico.reissmann@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #ifndef JLM_RVSDG_STRUCTURAL_NODE_HPP
7 #define JLM_RVSDG_STRUCTURAL_NODE_HPP
8 
9 #include <jlm/rvsdg/node.hpp>
10 #include <jlm/rvsdg/region.hpp>
13 
14 namespace jlm::rvsdg
15 {
16 
17 /* structural node */
18 
19 class StructuralInput;
20 class StructuralOperation;
21 class StructuralOutput;
22 
23 class StructuralNode : public Node
24 {
29 
32 
33 public:
34  ~StructuralNode() noexcept override;
35 
36 protected:
37  StructuralNode(rvsdg::Region * region, size_t nsubregions);
38 
39 public:
40  std::string
41  DebugString() const override;
42 
43  inline size_t
44  nsubregions() const noexcept
45  {
46  return subregions_.size();
47  }
48 
49  [[nodiscard]] rvsdg::Region *
50  subregion(size_t index) const noexcept
51  {
52  JLM_ASSERT(index < nsubregions());
53  return subregions_[index].get();
54  }
55 
58  {
59  return { SubregionIterator(subregions_.begin()), SubregionIterator(subregions_.end()) };
60  }
61 
63  Subregions() const
64  {
65  return { SubregionConstIterator(subregions_.begin()),
67  }
68 
69  [[nodiscard]] inline StructuralInput *
70  input(size_t index) const noexcept;
71 
72  [[nodiscard]] inline StructuralOutput *
73  output(size_t index) const noexcept;
74 
75 protected:
77  addInput(std::unique_ptr<StructuralInput> input, bool notifyRegion);
78 
80  addOutput(std::unique_ptr<StructuralOutput> input);
81 
82 private:
83  std::vector<std::unique_ptr<rvsdg::Region>> subregions_;
84 };
85 
86 /* structural input class */
87 
90 
91 class StructuralInput : public NodeInput
92 {
94 
95 public:
96  ~StructuralInput() noexcept override;
97 
100  jlm::rvsdg::Output * origin,
101  std::shared_ptr<const rvsdg::Type> type);
102 
104  node() const noexcept
105  {
106  return static_cast<StructuralNode *>(NodeInput::node());
107  }
108 
110 };
111 
112 /* structural output class */
113 
116 
118 {
120 
121 public:
122  ~StructuralOutput() noexcept override;
123 
124  StructuralOutput(StructuralNode * node, std::shared_ptr<const rvsdg::Type> type);
125 
127  node() const noexcept
128  {
129  return static_cast<StructuralNode *>(NodeOutput::node());
130  }
131 
133 };
134 
135 /* structural node method definitions */
136 
137 inline StructuralInput *
138 StructuralNode::input(size_t index) const noexcept
139 {
140  return static_cast<StructuralInput *>(Node::input(index));
141 }
142 
143 inline StructuralOutput *
144 StructuralNode::output(size_t index) const noexcept
145 {
146  return static_cast<StructuralOutput *>(Node::output(index));
147 }
148 
149 inline StructuralInput *
150 StructuralNode::addInput(std::unique_ptr<StructuralInput> input, bool notifyRegion)
151 {
152  return static_cast<StructuralInput *>(Node::addInput(std::move(input), notifyRegion));
153 }
154 
155 inline StructuralOutput *
156 StructuralNode::addOutput(std::unique_ptr<StructuralOutput> output)
157 {
158  return static_cast<StructuralOutput *>(Node::addOutput(std::move(output)));
159 }
160 
161 template<class Operation>
162 bool
163 Region::ContainsOperation(const rvsdg::Region & region, bool checkSubregions)
164 {
165  for (auto & node : region.Nodes())
166  {
167  if (auto simpleNode = dynamic_cast<const SimpleNode *>(&node))
168  {
169  if (is<Operation>(simpleNode->GetOperation()))
170  {
171  return true;
172  }
173  }
174 
175  if (!checkSubregions)
176  {
177  continue;
178  }
179 
180  if (auto structuralNode = dynamic_cast<const StructuralNode *>(&node))
181  {
182  for (size_t n = 0; n < structuralNode->nsubregions(); n++)
183  {
184  if (ContainsOperation<Operation>(*structuralNode->subregion(n), checkSubregions))
185  {
186  return true;
187  }
188  }
189  }
190  }
191 
192  return false;
193 }
194 
195 template<class NodeType>
196 bool
197 Region::ContainsNodeType(const rvsdg::Region & region, bool checkSubregions)
198 {
199  for (auto & node : region.Nodes())
200  {
201  if (dynamic_cast<const NodeType *>(&node))
202  {
203  return true;
204  }
205 
206  if (!checkSubregions)
207  {
208  continue;
209  }
210 
211  if (auto structuralNode = dynamic_cast<const StructuralNode *>(&node))
212  {
213  for (size_t n = 0; n < structuralNode->nsubregions(); n++)
214  {
215  if (ContainsNodeType<NodeType>(*structuralNode->subregion(n), checkSubregions))
216  {
217  return true;
218  }
219  }
220  }
221  }
222 
223  return false;
224 }
225 
226 }
227 
228 #endif
Output * origin() const noexcept
Definition: node.hpp:58
Node * node() const noexcept
Definition: node.hpp:560
Node * node() const noexcept
Definition: node.hpp:572
NodeOutput * addOutput(std::unique_ptr< NodeOutput > output)
Definition: node.hpp:732
rvsdg::Region * region() const noexcept
Definition: node.hpp:761
NodeInput * input(size_t index) const noexcept
Definition: node.hpp:615
NodeOutput * output(size_t index) const noexcept
Definition: node.hpp:650
NodeInput * addInput(std::unique_ptr< NodeInput > input, bool notifyRegion)
Definition: node.cpp:288
Represent acyclic RVSDG subgraphs.
Definition: region.hpp:213
static bool ContainsOperation(const rvsdg::Region &region, bool checkSubregions)
rvsdg::StructuralNode * node() const noexcept
Definition: region.hpp:369
static bool ContainsNodeType(const rvsdg::Region &region, bool checkSubregions)
NodeRange Nodes() noexcept
Definition: region.hpp:328
~StructuralInput() noexcept override
StructuralNode * node() const noexcept
SubregionConstIteratorRange Subregions() const
util::PtrIterator< const Region, std::vector< std::unique_ptr< Region > >::const_iterator > SubregionConstIterator
std::string DebugString() const override
~StructuralNode() noexcept override
StructuralInput * addInput(std::unique_ptr< StructuralInput > input, bool notifyRegion)
StructuralOutput * addOutput(std::unique_ptr< StructuralOutput > input)
SubregionIteratorRange Subregions()
util::IteratorRange< SubregionIterator > SubregionIteratorRange
std::vector< std::unique_ptr< rvsdg::Region > > subregions_
util::PtrIterator< Region, std::vector< std::unique_ptr< Region > >::iterator > SubregionIterator
size_t nsubregions() const noexcept
StructuralOutput * output(size_t index) const noexcept
StructuralInput * input(size_t index) const noexcept
rvsdg::Region * subregion(size_t index) const noexcept
util::IteratorRange< SubregionConstIterator > SubregionConstIteratorRange
~StructuralOutput() noexcept override
StructuralNode * node() const noexcept
#define JLM_ASSERT(x)
Definition: common.hpp:16
jlm::util::IntrusiveList< RegionResult, RegionResult::structural_output_accessor > result_list
jlm::util::IntrusiveList< RegionArgument, RegionArgument::structural_input_accessor > argument_list
static std::string type(const Node *n)
Definition: view.cpp:255