Jlm
Loading...
Searching...
No Matches
TestNodes.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2025 Nico Reißmann <nico.reissmann@gmail.com>
3 * See COPYING for terms of redistribution.
4 */
5
8
9namespace jlm::rvsdg
10{
11
13
14std::string
15TestStructuralOperation::debug_string() const
16{
17 return "TestStructuralOperation";
18}
19
20std::unique_ptr<Operation>
22{
23 return std::make_unique<TestStructuralOperation>(*this);
24}
25
27
30{
32 return singleton;
33}
34
37{
38 auto node = create(parent, nsubregions());
39
40 // copy inputs and arguments
41 for (auto & argument : subregion(0)->Arguments())
42 {
43 if (const auto input = argument->input())
44 {
45 auto oldInputVar = mapInput(*input);
46 auto & newOrigin = smap.lookup(*input->origin());
47 auto newInputVar = node->addInputWithArguments(newOrigin);
48 for (size_t n = 0; n < oldInputVar.argument.size(); n++)
49 {
50 auto oldArgument = oldInputVar.argument[n];
51 auto newArgument = newInputVar.argument[n];
53 }
54 }
55 else
56 {
57 auto newInputVar = node->addArguments(argument->Type());
58 for (auto & subregion : Subregions())
59 {
60 auto oldArgument = subregion.argument(argument->index());
61 JLM_ASSERT(oldArgument->input() == nullptr);
62 smap.insert(oldArgument, newInputVar.argument[subregion.index()]);
63 }
64 }
65 }
66
67 JLM_ASSERT(ninputs() == node->ninputs());
68 for (auto & subregion : Subregions())
69 {
70 JLM_ASSERT(subregion.narguments() == node->subregion(subregion.index())->narguments());
71 }
72
73 // copy subregions
74 for (auto & subregion : Subregions())
75 {
76 subregion.copy(node->subregion(subregion.index()), smap);
77 }
78
79 // copy results and outputs
80 for (auto & result : subregion(0)->Results())
81 {
82 if (const auto output = result->output())
83 {
85
86 std::vector<Output *> newOrigins;
87 for (auto oldOutputVarResult : oldOutputVar.result)
88 {
89 auto & newOrigin = smap.lookup(*oldOutputVarResult->origin());
90 newOrigins.push_back(&newOrigin);
91 }
92 auto newOutputVar = node->addOutputWithResults(newOrigins);
93 smap.insert(oldOutputVar.output, newOutputVar.output);
94 }
95 else
96 {
97 std::vector<Output *> newOrigins;
98 for (auto & subregion : Subregions())
99 {
100 auto subregionResult = subregion.result(result->index());
101 JLM_ASSERT(subregionResult->output() == nullptr);
102 auto & newOrigin = smap.lookup(*subregionResult->origin());
103 newOrigins.push_back(&newOrigin);
104 }
105 node->addResults(newOrigins);
106 }
107 }
108
109 JLM_ASSERT(noutputs() == node->noutputs());
110 for (auto & subregion : Subregions())
111 {
112 JLM_ASSERT(subregion.nresults() == node->subregion(subregion.index())->nresults());
113 }
114
115 return node;
116}
117
120{
122
124 inputVar.input = this->input(input.index());
125 for (auto & subregion : Subregions())
126 {
127 for (auto & argument : subregion.Arguments())
128 {
129 if (argument->input() == inputVar.input)
130 {
131 inputVar.argument.push_back(argument);
132 }
133 }
134 }
135
136 JLM_ASSERT(inputVar.argument.size() == nsubregions());
137 return inputVar;
138}
139
142{
144
146 outputVar.output = this->output(output.index());
147 for (auto & subregion : Subregions())
148 {
149 for (auto & result : subregion.Results())
150 {
151 if (result->output() == outputVar.output)
152 {
153 outputVar.result.push_back(result);
154 }
155 }
156 }
157
158 JLM_ASSERT(outputVar.result.size() == nsubregions());
159 return outputVar;
160}
161
164{
165 InputVar inputVar{ &addInputOnly(origin), {} };
166
167 for (auto & subregion : Subregions())
168 {
169 const auto argument = &RegionArgument::Create(
170 subregion,
171 util::assertedCast<StructuralInput>(inputVar.input),
172 inputVar.input->Type());
173 inputVar.argument.push_back(argument);
174 }
175
176 return inputVar;
177}
178
179void
181{
182 if (index >= ninputs())
183 throw std::out_of_range("Invalid input index.");
184
185 auto in = input(index);
186 for (auto & argument : in->arguments)
187 {
188 argument.region()->RemoveArguments({ argument.index() });
189 }
190
191 RemoveInputs({ index });
192}
193
195TestStructuralNode::addArguments(const std::shared_ptr<const Type> & type)
196{
197 std::vector<RegionArgument *> arguments;
198 for (auto & subregion : Subregions())
199 {
200 const auto argument = &RegionArgument::Create(subregion, nullptr, type);
201 arguments.push_back(argument);
202 }
203
204 return { nullptr, std::move(arguments) };
205}
206
209{
210 return *addInput(std::make_unique<StructuralInput>(this, &origin, origin.Type()), true);
211}
212
214TestStructuralNode::addOutputOnly(std::shared_ptr<const Type> type)
215{
216 return *addOutput(std::make_unique<StructuralOutput>(this, std::move(type)));
217}
218
221{
222 if (origins.size() != nsubregions())
223 throw util::Error("Insufficient number of origins.");
224
225 size_t n = 0;
227 for (auto & subregion : Subregions())
228 {
229 const auto origin = origins[n++];
230 const auto result = &RegionResult::Create(
231 subregion,
232 *origin,
233 util::assertedCast<StructuralOutput>(outputVar.output),
234 origin->Type());
235 outputVar.result.push_back(result);
236 }
237
238 return outputVar;
239}
240
241void
243{
244 if (index >= noutputs())
245 throw std::out_of_range("Invalid output index.");
246
247 auto out = output(index);
248 for (auto & result : out->results)
249 {
250 result.region()->RemoveResults({ result.index() });
251 }
252
253 RemoveOutputs({ index });
254}
255
257TestStructuralNode::addResults(const std::vector<Output *> & origins)
258{
259 if (origins.size() != nsubregions())
260 throw util::Error("Insufficient number of origins.");
261
262 size_t n = 0;
263 std::vector<RegionResult *> results;
264 for (auto & subregion : Subregions())
265 {
266 const auto origin = origins[n++];
267 const auto result = &RegionResult::Create(subregion, *origin, nullptr, origin->Type());
268 results.push_back(result);
269 }
270
271 return { nullptr, std::move(results) };
272}
273
274}
util::HashSet< rvsdg::Output * > arguments
size_t index() const noexcept
Definition node.hpp:52
Output * origin() const noexcept
Definition node.hpp:58
size_t RemoveInputs(const util::HashSet< size_t > &indices)
Definition node.cpp:306
size_t ninputs() const noexcept
Definition node.hpp:609
size_t noutputs() const noexcept
Definition node.hpp:644
size_t RemoveOutputs(const util::HashSet< size_t > &indices)
Definition node.cpp:342
size_t index() const noexcept
Definition node.hpp:274
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
Definition node.hpp:366
static RegionArgument & Create(rvsdg::Region &region, StructuralInput *input, std::shared_ptr< const rvsdg::Type > type)
Creates region entry argument.
Definition region.cpp:63
static RegionResult & Create(rvsdg::Region &region, rvsdg::Output &origin, StructuralOutput *output, std::shared_ptr< const rvsdg::Type > type)
Create region exit result.
Definition region.cpp:112
Represent acyclic RVSDG subgraphs.
Definition region.hpp:213
RegionArgument * argument(size_t index) const noexcept
Definition region.hpp:466
RegionArgumentRange Arguments() noexcept
Definition region.hpp:319
void copy(Region *target, SubstitutionMap &smap) const
Copy a region with substitutions.
Definition region.cpp:317
size_t nresults() const noexcept
Definition region.hpp:494
RegionResult * result(size_t index) const noexcept
Definition region.hpp:500
size_t index() const noexcept
Definition region.hpp:310
size_t narguments() const noexcept
Definition region.hpp:460
RegionResultRange Results() noexcept
Definition region.hpp:337
StructuralInput * addInput(std::unique_ptr< StructuralInput > input, bool notifyRegion)
StructuralOutput * addOutput(std::unique_ptr< StructuralOutput > input)
SubregionIteratorRange Subregions()
rvsdg::Region * subregion(size_t index) const noexcept
size_t nsubregions() const noexcept
StructuralOutput * output(size_t index) const noexcept
StructuralInput * input(size_t index) const noexcept
void removeInputAndArguments(size_t index)
OutputVar addOutputWithResults(const std::vector< Output * > &origins)
InputVar addInputWithArguments(Output &origin)
OutputVar mapOutput(const Output &output) const
~TestStructuralNode() noexcept override
OutputVar addResults(const std::vector< Output * > &origins)
InputVar mapInput(const Input &input) const
void removeOutputAndResults(size_t index)
StructuralOutput & addOutputOnly(std::shared_ptr< const Type > type)
InputVar addArguments(const std::shared_ptr< const Type > &type)
static TestStructuralNode * create(Region *parent, const size_t numSubregions)
TestStructuralNode * copy(Region *region, SubstitutionMap &smap) const override
Copy a node with substitutions.
Definition TestNodes.cpp:36
StructuralInput & addInputOnly(Output &origin)
std::unique_ptr< Operation > copy() const override
Definition TestNodes.cpp:21
~TestStructuralOperation() noexcept override
#define JLM_ASSERT(x)
Definition common.hpp:16
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872
A variable routed in a TestStructuralNode.
Definition TestNodes.hpp:42
A variable routed out of a TestStructuralNode.
Definition TestNodes.hpp:51