Jlm
Loading...
Searching...
No Matches
GammaTests.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 2015 Nico Reißmann <nico.reissmann@gmail.com>
3 * See COPYING for terms of redistribution.
4 */
5
6#include <gtest/gtest.h>
7
9#include <jlm/rvsdg/gamma.hpp>
11#include <jlm/rvsdg/view.hpp>
12
13TEST(GammaTests, test_gamma)
14{
15 using namespace jlm::rvsdg;
16
17 Graph graph;
18 auto cmp = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(2), "");
19 auto v0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "");
20 auto v1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "");
21 auto v2 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "");
22 auto v3 = &jlm::rvsdg::GraphImport::Create(graph, ControlType::Create(2), "");
23
24 auto & matchNode = MatchOperation::CreateNode(*cmp, { { 0, 0 }, { 1, 1 } }, 2, 3);
25
26 auto gamma = GammaNode::create(matchNode.output(0), 3);
27 auto ev0 = gamma->AddEntryVar(v0);
28 auto ev1 = gamma->AddEntryVar(v1);
29 auto ev2 = gamma->AddEntryVar(v2);
30 gamma->AddExitVar({ ev0.branchArgument[0], ev1.branchArgument[1], ev2.branchArgument[2] });
31
32 GraphExport::Create(*gamma->output(0), "dummy");
33
34 EXPECT_NE(gamma, nullptr);
35 EXPECT_EQ(gamma->GetOperation(), GammaOperation(3));
36
37 /* test gamma copy */
38
39 auto gamma2 = static_cast<StructuralNode *>(gamma)->copy(
40 &graph.GetRootRegion(),
41 { matchNode.output(0), v0, v1, v2 });
42 view(&graph.GetRootRegion(), stdout);
43 EXPECT_NE(dynamic_cast<const GammaNode *>(gamma2), nullptr);
44
45 /* test entry and exit variable iterators */
46
47 auto gamma3 = GammaNode::create(v3, 2);
48 EXPECT_TRUE(gamma3->GetEntryVars().empty());
49 EXPECT_TRUE(gamma3->GetExitVars().empty());
50}
51
52TEST(GammaTests, test_predicate_reduction)
53{
54 using namespace jlm::rvsdg;
55
56 // Arrange
57 Graph graph;
58 BitType bits2(2);
59
60 auto v0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "");
61 auto v1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "");
62 auto v2 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "");
63
64 auto pred = &ControlConstantOperation::create(graph.GetRootRegion(), 3, 1);
65
66 auto gamma = GammaNode::create(pred, 3);
67 auto ev0 = gamma->AddEntryVar(v0);
68 auto ev1 = gamma->AddEntryVar(v1);
69 auto ev2 = gamma->AddEntryVar(v2);
70 gamma->AddExitVar({ ev0.branchArgument[0], ev1.branchArgument[1], ev2.branchArgument[2] });
71
72 auto & r = GraphExport::Create(*gamma->output(0), "");
73
74 view(&graph.GetRootRegion(), stdout);
75
76 // Act
77 auto gammaNode = TryGetOwnerNode<GammaNode>(*r.origin());
78 ReduceGammaWithStaticallyKnownPredicate(*gammaNode);
79 view(&graph.GetRootRegion(), stdout);
80
81 // Assert
82 EXPECT_EQ(r.origin(), v1);
83
84 graph.PruneNodes();
85 EXPECT_EQ(graph.GetRootRegion().numNodes(), 0u);
86}
87
88TEST(GammaTests, test_invariant_reduction)
89{
90 using namespace jlm::rvsdg;
91
92 // Arrange
93 Graph graph;
94 const auto valueType = TestType::createValueType();
95
96 const auto predicate = &jlm::rvsdg::GraphImport::Create(graph, ControlType::Create(2), "");
97 const auto value = &jlm::rvsdg::GraphImport::Create(graph, valueType, "");
98
99 const auto gammaNode = GammaNode::create(predicate, 2);
100 auto [input, branchArgument] = gammaNode->AddEntryVar(value);
101 gammaNode->AddExitVar(branchArgument);
102
103 auto & ex = GraphExport::Create(*gammaNode->output(0), "");
104
105 view(&graph.GetRootRegion(), stdout);
106
107 // Act
108 const auto success = ReduceGammaInvariantVariables(*gammaNode);
109 view(&graph.GetRootRegion(), stdout);
110
111 // Assert
112 EXPECT_TRUE(success);
113 EXPECT_EQ(ex.origin(), value);
114
115 graph.PruneNodes();
116 EXPECT_EQ(graph.GetRootRegion().numNodes(), 0u);
117}
118
119TEST(GammaTests, test_control_constant_reduction)
120{
121 using namespace jlm::rvsdg;
122
123 // Arrange
124 Graph graph;
125
126 auto x = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(1), "x");
127
128 auto & matchNode = MatchOperation::CreateNode(*x, { { 0, 0 } }, 1, 2);
129
130 auto gamma = GammaNode::create(matchNode.output(0), 2);
131
132 auto t = &ControlConstantOperation::createTrue(*gamma->subregion(0));
133 auto f = &ControlConstantOperation::createFalse(*gamma->subregion(1));
134
135 auto n0 = &ControlConstantOperation::create(*gamma->subregion(0), 3, 0);
136 auto n1 = &ControlConstantOperation::create(*gamma->subregion(1), 3, 1);
137
138 auto xv1 = gamma->AddExitVar({ t, f });
139 auto xv2 = gamma->AddExitVar({ n0, n1 });
140
141 auto & ex1 = GraphExport::Create(*xv1.output, "");
142 auto & ex2 = GraphExport::Create(*xv2.output, "");
143
144 view(&graph.GetRootRegion(), stdout);
145
146 // Act
147 auto gammaNode = TryGetOwnerNode<GammaNode>(*ex1.origin());
148 ReduceGammaControlConstant(*gammaNode);
149 view(&graph.GetRootRegion(), stdout);
150
151 // Assert
152 {
153 auto [matchNode, matchOperation] = TryGetSimpleNodeAndOptionalOp<MatchOperation>(*ex1.origin());
154 EXPECT_TRUE(matchNode && matchOperation);
155 EXPECT_EQ(matchOperation->default_alternative(), 0u);
156
157 EXPECT_EQ(TryGetOwnerNode<Node>(*ex2.origin()), gamma);
158 }
159}
160
161TEST(GammaTests, test_control_constant_reduction2)
162{
163 using namespace jlm::rvsdg;
164
165 // Arrange
166 Graph graph;
167
168 auto import = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(2), "import");
169
170 auto & matchNode = MatchOperation::CreateNode(*import, { { 3, 2 }, { 2, 1 }, { 1, 0 } }, 3, 4);
171
172 auto gamma = GammaNode::create(matchNode.output(0), 4);
173
174 auto t1 = &ControlConstantOperation::createTrue(*gamma->subregion(0));
175 auto t2 = &ControlConstantOperation::createTrue(*gamma->subregion(1));
176 auto t3 = &ControlConstantOperation::createTrue(*gamma->subregion(2));
177 auto f = &ControlConstantOperation::createFalse(*gamma->subregion(3));
178
179 auto xv = gamma->AddExitVar({ t1, t2, t3, f });
180
181 auto & ex = GraphExport::Create(*xv.output, "");
182
183 jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
184
185 // Act
186 auto gammaNode = TryGetOwnerNode<GammaNode>(*ex.origin());
187 ReduceGammaControlConstant(*gammaNode);
188 jlm::rvsdg::view(&graph.GetRootRegion(), stdout);
189
190 // Assert
191 auto match = TryGetOwnerNode<SimpleNode>(*ex.origin());
192 EXPECT_TRUE(is<MatchOperation>(match->GetOperation()));
193}
194
195TEST(GammaTests, TestPruneOutputs)
196{
197 using namespace jlm::rvsdg;
198
199 // Arrange
200 Graph rvsdg;
201 auto vt = TestType::createValueType();
202 ControlType ct(2);
203
204 auto predicate = &jlm::rvsdg::GraphImport::Create(rvsdg, ControlType::Create(2), "");
205 auto v0 = &jlm::rvsdg::GraphImport::Create(rvsdg, vt, "");
206 auto v1 = &jlm::rvsdg::GraphImport::Create(rvsdg, vt, "");
207 auto v2 = &jlm::rvsdg::GraphImport::Create(rvsdg, vt, "");
208 auto v3 = &jlm::rvsdg::GraphImport::Create(rvsdg, vt, "");
209
210 auto gammaNode = GammaNode::create(predicate, 2);
211 auto gammaInput0 = gammaNode->AddEntryVar(v0);
212 auto gammaInput1 = gammaNode->AddEntryVar(v1);
213 auto gammaInput2 = gammaNode->AddEntryVar(v2);
214 auto gammaInput3 = gammaNode->AddEntryVar(v3);
215
216 auto gammaOutput0 = gammaNode->AddExitVar(gammaInput0.branchArgument);
217 gammaNode->AddExitVar(gammaInput1.branchArgument);
218 auto gammaOutput2 = gammaNode->AddExitVar(gammaInput2.branchArgument);
219 gammaNode->AddExitVar(gammaInput3.branchArgument);
220
221 GraphExport::Create(*gammaOutput0.output, "");
222 GraphExport::Create(*gammaOutput2.output, "");
223
224 // Act
225 gammaNode->PruneExitVars();
226
227 // Assert
228 EXPECT_EQ(gammaNode->noutputs(), 2u);
229 EXPECT_EQ(gammaNode->subregion(0)->nresults(), 2u);
230 EXPECT_EQ(gammaNode->subregion(1)->nresults(), 2u);
231
232 EXPECT_EQ(gammaOutput0.output->index(), 0u);
233 EXPECT_EQ(gammaNode->GetExitVars()[0].output, gammaOutput0.output);
234
235 EXPECT_EQ(gammaOutput2.output->index(), 1u);
236 EXPECT_EQ(gammaNode->GetExitVars()[1].output, gammaOutput2.output);
237}
238
239TEST(GammaTests, TestIsInvariant)
240{
241 using namespace jlm::rvsdg;
242
243 // Arrange
244 Graph rvsdg;
245 auto vt = TestType::createValueType();
246 ControlType ct(2);
247
248 auto predicate = &jlm::rvsdg::GraphImport::Create(rvsdg, ControlType::Create(2), "");
249 auto v0 = &jlm::rvsdg::GraphImport::Create(rvsdg, vt, "");
250 auto v1 = &jlm::rvsdg::GraphImport::Create(rvsdg, vt, "");
251
252 auto gammaNode = GammaNode::create(predicate, 2);
253 auto gammaInput0 = gammaNode->AddEntryVar(v0);
254 auto gammaInput1 = gammaNode->AddEntryVar(v1);
255 auto gammaInput2 = gammaNode->AddEntryVar(v1);
256
257 auto gammaOutput0 = gammaNode->AddExitVar(gammaInput0.branchArgument);
258 auto gammaOutput1 =
259 gammaNode->AddExitVar({ gammaInput1.branchArgument[0], gammaInput2.branchArgument[1] });
260 auto gammaOutput2 =
261 gammaNode->AddExitVar({ gammaInput0.branchArgument[0], gammaInput2.branchArgument[1] });
262
263 // Act & Assert
264 std::optional<jlm::rvsdg::Output *> invariantOrigin;
265 invariantOrigin = jlm::rvsdg::GetGammaInvariantOrigin(*gammaNode, gammaOutput0);
266 EXPECT_NE(invariantOrigin, nullptr);
267 EXPECT_EQ(*invariantOrigin, v0);
268
269 invariantOrigin = jlm::rvsdg::GetGammaInvariantOrigin(*gammaNode, gammaOutput1);
270 EXPECT_NE(invariantOrigin, nullptr);
271 EXPECT_EQ(*invariantOrigin, v1);
272
273 invariantOrigin = jlm::rvsdg::GetGammaInvariantOrigin(*gammaNode, gammaOutput2);
274 EXPECT_EQ(invariantOrigin, std::nullopt);
275}
static const auto vt
Definition PullTests.cpp:16
Conditional operator / pattern matching.
Definition gamma.hpp:99
static GraphImport & Create(Graph &graph, std::shared_ptr< const rvsdg::Type > type, std::string name)
Definition graph.cpp:36
Region & GetRootRegion() const noexcept
Definition graph.hpp:99
void PruneNodes()
Definition graph.hpp:116
size_t numNodes() const noexcept
Definition region.hpp:510
std::string view(const rvsdg::Region *region)
Definition view.cpp:142
std::optional< rvsdg::Output * > GetGammaInvariantOrigin(const GammaNode &gamma, const GammaNode::ExitVar &exitvar)
Determines whether a gamma exit var is path-invariant.
Definition gamma.cpp:509
TEST(GammaTests, test_gamma)