Jlm
Loading...
Searching...
No Matches
theta.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2012 2013 2014 Helge Bahmann <hcb@chaoticmind.net>
3 * Copyright 2013 2014 2015 Nico Reißmann <nico.reissmann@gmail.com>
4 * See COPYING for terms of redistribution.
5 */
6
7#include <algorithm>
9#include <jlm/rvsdg/theta.hpp>
10
11#include <algorithm>
12
13namespace jlm::rvsdg
14{
15
17
18std::string
19ThetaOperation::debug_string() const
20{
21 return "THETA";
22}
23
24std::unique_ptr<Operation>
26{
27 return std::make_unique<ThetaOperation>(*this);
28}
29
31
33ThetaNode::GetOperation() const noexcept
34{
35 // Theta presently has no parametrization, so we can indeed
36 // just return a singleton here.
37 static const ThetaOperation singleton;
38 return singleton;
39}
40
47
50{
51 Node::addInput(std::make_unique<StructuralInput>(this, origin, origin->Type()), true);
52 Node::addOutput(std::make_unique<StructuralOutput>(this, origin->Type()));
53
54 auto input = ThetaNode::input(ninputs() - 1);
55 auto output = ThetaNode::output(noutputs() - 1);
58
60}
61
62void
64{
69 for (const auto & [input, pre, post, output] : loopVars)
70 {
72
73 // If the pre argument has a user, it can only be the corresponding post result
74 JLM_ASSERT(pre->nusers() <= 1);
75 if (pre->nusers() == 1)
76 {
77 JLM_ASSERT(post->origin() == pre);
78 }
79
80 inputIndices.insert(input->index());
81 argumentIndices.insert(pre->index());
82 resultIndices.insert(post->index());
83 outputIndices.insert(output->index());
84 }
85
88
91
94
97}
98
101{
103 auto theta = create(region);
104
105 /* add loop variables */
106 std::vector<LoopVar> oldLoopVars = GetLoopVars();
107 std::vector<LoopVar> newLoopVars;
108 for (auto olv : oldLoopVars)
109 {
110 auto nlv = theta->AddLoopVar(&smap.lookup(*olv.input->origin()));
111 newLoopVars.push_back(nlv);
112 rmap.insert(olv.pre, nlv.pre);
113 }
114
115 /* copy subregion */
116 subregion()->copy(theta->subregion(), rmap);
117 theta->set_predicate(&rmap.lookup(*predicate()->origin()));
118
119 /* redirect loop variables */
120 for (size_t i = 0; i < oldLoopVars.size(); ++i)
121 {
122 newLoopVars[i].post->divert_to(&rmap.lookup(*oldLoopVars[i].post->origin()));
124 }
125
126 return theta;
127}
128
131{
133 return LoopVar{ const_cast<rvsdg::Input *>(&input),
135 subregion()->result(input.index() + 1),
136 output(input.index()) };
137}
138
141{
143 return LoopVar{ input(argument.index()),
144 const_cast<rvsdg::Output *>(&argument),
145 subregion()->result(argument.index() + 1),
146 output(argument.index()) };
147}
148
151{
153 if (result.index() == 0)
154 {
155 // This is the loop continuation predicate.
156 // There is nothing sensible to return here.
157 throw std::logic_error("cannot map loop continuation predicate to loop variable");
158 }
159 return LoopVar{ input(result.index() - 1),
160 subregion()->argument(result.index() - 1),
161 const_cast<rvsdg::Input *>(&result),
162 output(result.index() - 1) };
163}
164
167{
169 return LoopVar{ input(output.index()),
171 subregion()->result(output.index() + 1),
172 const_cast<rvsdg::Output *>(&output) };
173}
174
175[[nodiscard]] std::vector<ThetaNode::LoopVar>
177{
178 std::vector<LoopVar> loopvars;
179 for (size_t index = 0; index < ninputs(); ++index)
180 {
181 loopvars.push_back(LoopVar{ input(index),
182 subregion()->argument(index),
183 subregion()->result(index + 1),
184 output(index) });
185 }
186 return loopvars;
187}
188
189}
static Output & createFalse(Region &region)
Definition control.hpp:134
static std::shared_ptr< const ControlType > Create(std::size_t nalternatives)
Instantiates control type.
Definition control.cpp:50
size_t index() const noexcept
Definition node.hpp:52
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
Definition node.hpp:67
NodeInput * input(size_t index) const noexcept
Definition node.hpp:615
NodeOutput * output(size_t index) const noexcept
Definition node.hpp:650
size_t RemoveInputs(const util::HashSet< size_t > &indices)
Definition node.cpp:306
rvsdg::Region * region() const noexcept
Definition node.hpp:761
size_t ninputs() const noexcept
Definition node.hpp:609
NodeOutput * addOutput(std::unique_ptr< NodeOutput > output)
Definition node.hpp:732
size_t noutputs() const noexcept
Definition node.hpp:644
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
size_t index() const noexcept
Definition node.hpp:274
bool IsDead() const noexcept
Definition node.hpp:295
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
size_t RemoveResults(const util::HashSet< size_t > &indices)
Definition region.cpp:281
RegionArgument * argument(size_t index) const noexcept
Definition region.hpp:466
void copy(Region *target, SubstitutionMap &smap) const
Copy a region with substitutions.
Definition region.cpp:317
RegionResult * result(size_t index) const noexcept
Definition region.hpp:500
size_t RemoveArguments(const util::HashSet< size_t > &indices)
Definition region.cpp:213
StructuralOutput * output(size_t index) const noexcept
StructuralInput * input(size_t index) const noexcept
LoopVar MapOutputLoopVar(const rvsdg::Output &output) const
Maps variable at exit to full varibale description.
Definition theta.cpp:166
void RemoveLoopVars(std::vector< LoopVar > loopVars)
Removes loop variables.
Definition theta.cpp:63
LoopVar MapPreLoopVar(const rvsdg::Output &argument) const
Maps variable at start of loop iteration to full varibale description.
Definition theta.cpp:140
std::vector< LoopVar > GetLoopVars() const
Returns all loop variables.
Definition theta.cpp:176
ThetaNode * copy(rvsdg::Region *region, rvsdg::SubstitutionMap &smap) const override
Copy a node with substitutions.
Definition theta.cpp:100
LoopVar MapPostLoopVar(const rvsdg::Input &result) const
Maps variable at end of loop iteration to full varibale description.
Definition theta.cpp:150
rvsdg::Region * subregion() const noexcept
Definition theta.hpp:79
static ThetaNode * create(rvsdg::Region *parent)
Definition theta.hpp:73
LoopVar MapInputLoopVar(const rvsdg::Input &input) const
Maps variable at entry to full varibale description.
Definition theta.cpp:130
RegionResult * predicate() const noexcept
Definition theta.hpp:85
~ThetaNode() noexcept override
ThetaNode(rvsdg::Region &parent)
Definition theta.cpp:41
LoopVar AddLoopVar(rvsdg::Output *origin)
Creates a new loop-carried variable.
Definition theta.cpp:49
std::unique_ptr< Operation > copy() const override
Definition theta.cpp:25
~ThetaOperation() 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
Description of a loop-carried variable.
Definition theta.hpp:50