Jlm
SimpleOperationTests.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 
6 #include <gtest/gtest.h>
7 
11 #include <jlm/rvsdg/TestType.hpp>
12 #include <jlm/rvsdg/view.hpp>
13 
14 TEST(SimpleOperationTests, NormalizeSimpleOperationCne_NodesWithoutOperands)
15 {
16  using namespace jlm::rvsdg;
17 
18  // Arrange
19  Graph graph;
20  const auto valueType = TestType::createValueType();
21  const auto stateType = TestType::createStateType();
22 
23  auto & nullaryValueNode1 = CreateOpNode<TestNullaryOperation>(graph.GetRootRegion(), valueType);
24  auto & nullaryValueNode2 = CreateOpNode<TestNullaryOperation>(graph.GetRootRegion(), valueType);
25  auto & nullaryStateNode1 = CreateOpNode<TestNullaryOperation>(graph.GetRootRegion(), stateType);
26  auto & nullaryStateNode2 = CreateOpNode<TestNullaryOperation>(graph.GetRootRegion(), stateType);
27 
28  auto & exNullaryValueNode1 = GraphExport::Create(*nullaryValueNode1.output(0), "nvn1");
29  auto & exNullaryValueNode2 = GraphExport::Create(*nullaryValueNode2.output(0), "nvn2");
30  auto & exNullaryStateNode1 = GraphExport::Create(*nullaryStateNode1.output(0), "nsn1");
31  auto & exNullaryStateNode2 = GraphExport::Create(*nullaryStateNode2.output(0), "nsn2");
32 
33  view(graph, stdout);
34 
35  // Act
36  auto NormalizeCne = [&](const SimpleOperation & operation, const std::vector<Output *> & operands)
37  {
39  graph.GetRootRegion(),
40  operation,
41  operands);
42  };
43 
44  // Act
45  ReduceNode<SimpleOperation>(
46  NormalizeCne,
47  *TryGetOwnerNode<SimpleNode>(*exNullaryValueNode1.origin()));
48  ReduceNode<SimpleOperation>(
49  NormalizeCne,
50  *TryGetOwnerNode<SimpleNode>(*exNullaryValueNode2.origin()));
51  ReduceNode<SimpleOperation>(
52  NormalizeCne,
53  *TryGetOwnerNode<SimpleNode>(*exNullaryStateNode1.origin()));
54  ReduceNode<SimpleOperation>(
55  NormalizeCne,
56  *TryGetOwnerNode<SimpleNode>(*exNullaryStateNode2.origin()));
57  graph.PruneNodes();
58 
59  view(graph, stdout);
60 
61  // Assert
62  EXPECT_EQ(exNullaryValueNode1.origin(), exNullaryValueNode2.origin());
63  EXPECT_EQ(exNullaryStateNode1.origin(), exNullaryStateNode2.origin());
64  EXPECT_NE(exNullaryValueNode1.origin(), exNullaryStateNode2.origin());
65 }
66 
67 TEST(SimpleOperationTests, NormalizeSimpleOperationCne_NodesWithOperands)
68 {
69  using namespace jlm::rvsdg;
70 
71  // Arrange
72  Graph graph;
73  const auto valueType = TestType::createValueType();
74  const auto stateType = TestType::createStateType();
75 
76  auto v1 = &GraphImport::Create(graph, valueType, "v1");
77  auto s1 = &GraphImport::Create(graph, stateType, "s1");
78 
79  auto & valueNode1 = CreateOpNode<TestUnaryOperation>({ v1 }, valueType, valueType);
80  auto & valueNode2 = CreateOpNode<TestUnaryOperation>({ v1 }, valueType, valueType);
81  auto & stateNode1 = CreateOpNode<TestUnaryOperation>({ s1 }, stateType, stateType);
82  auto & stateNode2 = CreateOpNode<TestUnaryOperation>({ s1 }, stateType, stateType);
83 
84  auto & exValueNode1 = GraphExport::Create(*valueNode1.output(0), "nvn1");
85  auto & exValueNode2 = GraphExport::Create(*valueNode2.output(0), "nvn2");
86  auto & exStateNode1 = GraphExport::Create(*stateNode1.output(0), "nsn1");
87  auto & exStateNode2 = GraphExport::Create(*stateNode2.output(0), "nsn2");
88 
89  view(graph, stdout);
90 
91  // Act
92  auto NormalizeCne = [&](const SimpleOperation & operation, const std::vector<Output *> & operands)
93  {
95  graph.GetRootRegion(),
96  operation,
97  operands);
98  };
99 
100  // Act
101  ReduceNode<SimpleOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*exValueNode1.origin()));
102  ReduceNode<SimpleOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*exValueNode2.origin()));
103  ReduceNode<SimpleOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*exStateNode1.origin()));
104  ReduceNode<SimpleOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*exStateNode2.origin()));
105  graph.PruneNodes();
106 
107  view(graph, stdout);
108 
109  // Assert
110  EXPECT_EQ(exValueNode1.origin(), exValueNode2.origin());
111  EXPECT_EQ(exStateNode1.origin(), exStateNode2.origin());
112  EXPECT_NE(exValueNode1.origin(), exStateNode2.origin());
113 }
114 
115 TEST(SimpleOperationTests, NormalizeSimpleOperationCne_Mixed)
116 {
117  using namespace jlm::rvsdg;
118 
119  // Arrange
120  Graph graph;
121 
122  auto NormalizeCne =
123  [&](const SimpleOperation & operation, const std::vector<jlm::rvsdg::Output *> & operands)
124  {
126  graph.GetRootRegion(),
127  operation,
128  operands);
129  };
130 
131  auto valueType = TestType::createValueType();
132 
133  auto i = &jlm::rvsdg::GraphImport::Create(graph, valueType, "i");
134 
135  auto o1 = TestOperation::createNode(&graph.GetRootRegion(), {}, { valueType })->output(0);
136  auto o2 = TestOperation::createNode(&graph.GetRootRegion(), { i }, { valueType })->output(0);
137  auto o3 = TestOperation::createNode(&graph.GetRootRegion(), {}, { valueType })->output(0);
138  auto o4 = TestOperation::createNode(&graph.GetRootRegion(), { i }, { valueType })->output(0);
139 
140  auto & e1 = GraphExport::Create(*o1, "o1");
141  auto & e2 = GraphExport::Create(*o2, "o2");
142  auto & e3 = GraphExport::Create(*o3, "o3");
143  auto & e4 = GraphExport::Create(*o4, "o4");
144 
145  // Act & Assert
146  ReduceNode<TestOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*e1.origin()));
147  ReduceNode<TestOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*e2.origin()));
148  ReduceNode<TestOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*e3.origin()));
149  ReduceNode<TestOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*e4.origin()));
150 
151  EXPECT_EQ(e1.origin(), e3.origin());
152  EXPECT_EQ(e2.origin(), e4.origin());
153 
154  auto o5 = TestOperation::createNode(&graph.GetRootRegion(), {}, { valueType })->output(0);
155  auto & e5 = GraphExport::Create(*o5, "o5");
156  ReduceNode<TestOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*e5.origin()));
157  EXPECT_EQ(e5.origin(), e1.origin());
158 
159  auto o6 = TestOperation::createNode(&graph.GetRootRegion(), { i }, { valueType })->output(0);
160  auto & e6 = GraphExport::Create(*o6, "o6");
161  ReduceNode<TestOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*e6.origin()));
162  EXPECT_EQ(e6.origin(), e2.origin());
163 
164  auto o7 = TestOperation::createNode(&graph.GetRootRegion(), {}, { valueType })->output(0);
165  auto & e7 = GraphExport::Create(*o7, "o7");
166  EXPECT_NE(e7.origin(), e1.origin());
167 
168  ReduceNode<TestOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*e7.origin()));
169  EXPECT_EQ(e7.origin(), e1.origin());
170 }
171 
172 TEST(SimpleOperationTests, NormalizeSimpleOperationCne_Failure)
173 {
174  using namespace jlm::rvsdg;
175 
176  // Arrange
177  Graph graph;
178  const auto valueType = TestType::createValueType();
179  const auto stateType = TestType::createStateType();
180 
181  auto v1 = &GraphImport::Create(graph, valueType, "v1");
182  auto s1 = &GraphImport::Create(graph, stateType, "s1");
183 
184  auto & nullaryValueNode = CreateOpNode<TestNullaryOperation>(graph.GetRootRegion(), valueType);
185  auto & nullaryStateNode = CreateOpNode<TestNullaryOperation>(graph.GetRootRegion(), stateType);
186  auto & unaryValueNode = CreateOpNode<TestUnaryOperation>({ v1 }, valueType, valueType);
187  auto & unaryStateNode = CreateOpNode<TestUnaryOperation>({ s1 }, stateType, stateType);
188 
189  auto & exNullaryValueNode = GraphExport::Create(*nullaryValueNode.output(0), "nvn1");
190  auto & exNullaryStateNode = GraphExport::Create(*nullaryStateNode.output(0), "nvn2");
191  auto & exUnaryValueNode = GraphExport::Create(*unaryValueNode.output(0), "nsn1");
192  auto & exUnaryStateNode = GraphExport::Create(*unaryStateNode.output(0), "nsn2");
193 
194  view(graph, stdout);
195 
196  // Act
197  auto NormalizeCne = [&](const SimpleOperation & operation, const std::vector<Output *> & operands)
198  {
200  graph.GetRootRegion(),
201  operation,
202  operands);
203  };
204 
205  // Act
206  ReduceNode<SimpleOperation>(
207  NormalizeCne,
208  *TryGetOwnerNode<SimpleNode>(*exNullaryValueNode.origin()));
209  ReduceNode<SimpleOperation>(
210  NormalizeCne,
211  *TryGetOwnerNode<SimpleNode>(*exNullaryStateNode.origin()));
212  ReduceNode<SimpleOperation>(
213  NormalizeCne,
214  *TryGetOwnerNode<SimpleNode>(*exUnaryValueNode.origin()));
215  ReduceNode<SimpleOperation>(
216  NormalizeCne,
217  *TryGetOwnerNode<SimpleNode>(*exUnaryStateNode.origin()));
218  graph.PruneNodes();
219 
220  view(graph, stdout);
221 
222  // Assert
223  EXPECT_EQ(TryGetOwnerNode<Node>(*exNullaryValueNode.origin()), &nullaryValueNode);
224  EXPECT_EQ(TryGetOwnerNode<Node>(*exNullaryStateNode.origin()), &nullaryStateNode);
225  EXPECT_EQ(TryGetOwnerNode<Node>(*exUnaryValueNode.origin()), &unaryValueNode);
226  EXPECT_EQ(TryGetOwnerNode<Node>(*exUnaryStateNode.origin()), &unaryStateNode);
227 }
TEST(SimpleOperationTests, NormalizeSimpleOperationCne_NodesWithoutOperands)
static GraphExport & Create(Output &origin, std::string name)
Definition: graph.cpp:62
static GraphImport & Create(Graph &graph, std::shared_ptr< const rvsdg::Type > type, std::string name)
Definition: graph.cpp:36
void PruneNodes()
Definition: graph.hpp:116
Region & GetRootRegion() const noexcept
Definition: graph.hpp:99
NodeOutput * output(size_t index) const noexcept
Definition: simple-node.hpp:88
static SimpleNode * createNode(Region *region, const std::vector< Output * > &operands, std::vector< std::shared_ptr< const Type >> resultTypes)
static std::shared_ptr< const TestType > createStateType()
Definition: TestType.cpp:60
static std::shared_ptr< const TestType > createValueType()
Definition: TestType.cpp:67
std::optional< std::vector< rvsdg::Output * > > NormalizeSimpleOperationCommonNodeElimination(Region &region, const SimpleOperation &operation, const std::vector< rvsdg::Output * > &operands)
Performs common node elimination for a given operation and operands in a region.
Definition: simple-node.cpp:85
std::string view(const rvsdg::Region *region)
Definition: view.cpp:142
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
Definition: node.hpp:1049