6 #include <gtest/gtest.h>
16 TEST(RegionTests, IteratorRanges)
26 auto & subregion = *structuralNode->subregion(0);
27 auto & constSubregion = *
static_cast<const jlm::rvsdg::Region *
>(structuralNode->subregion(0));
29 auto & argument0 = *structuralNode->addArguments(valueType).
argument[0];
30 auto & argument1 = *structuralNode->addArguments(valueType).argument[0];
38 const auto outputVar0 = structuralNode->addResults({ topNode0->output(0) });
39 const auto outputVar1 = structuralNode->addResults({ node0->output(0) });
40 const auto outputVar2 = structuralNode->addResults({ node1->output(0) });
43 auto numArguments = std::distance(subregion.Arguments().begin(), subregion.Arguments().end());
44 EXPECT_EQ(numArguments, 2);
45 for (
auto & argument : constSubregion.Arguments())
47 EXPECT_TRUE(argument == &argument0 || argument == &argument1);
50 auto numTopNodes = std::distance(subregion.TopNodes().begin(), subregion.TopNodes().end());
51 EXPECT_EQ(numTopNodes, 1);
52 for (
auto & topNode : constSubregion.TopNodes())
54 EXPECT_EQ(&topNode, topNode0);
57 auto numNodes = std::distance(subregion.Nodes().begin(), subregion.Nodes().end());
58 EXPECT_EQ(numNodes, 4);
59 for (
auto & node : constSubregion.Nodes())
61 EXPECT_TRUE(&node == topNode0 || &node == node0 || &node == node1 || &node == bottomNode0);
65 std::distance(subregion.BottomNodes().begin(), subregion.BottomNodes().end());
66 EXPECT_EQ(numBottomNodes, 1);
67 for (
auto & bottomNode : constSubregion.BottomNodes())
69 EXPECT_EQ(&bottomNode, bottomNode0);
72 auto numResults = std::distance(subregion.Results().begin(), subregion.Results().end());
73 EXPECT_EQ(numResults, 3);
74 for (
auto & result : constSubregion.Results())
77 result == outputVar0.result[0] || result == outputVar1.result[0]
78 || result == outputVar2.result[0]);
93 auto inputVar1 = structuralNode1->addInputWithArguments(*
import);
95 structuralNode1->subregion(0),
97 inputVar1.argument[0],
101 auto inputVar2 = structuralNode2->addInputWithArguments(*
import);
106 jlm::rvsdg::Region::ContainsNodeType<TestStructuralNode>(graph.
GetRootRegion(),
false));
108 jlm::rvsdg::Region::ContainsOperation<TestUnaryOperation>(graph.
GetRootRegion(),
true));
110 jlm::rvsdg::Region::ContainsOperation<TestBinaryOperation>(graph.
GetRootRegion(),
true));
111 EXPECT_TRUE(!jlm::rvsdg::Region::ContainsOperation<TestOperation>(graph.
GetRootRegion(),
true));
114 TEST(RegionTests, IsRootRegion)
125 EXPECT_FALSE(structuralNode->subregion(0)->IsRootRegion());
128 TEST(RegionTests, NumRegions_EmptyRvsdg)
139 TEST(RegionTests, NumRegions_NonEmptyRvsdg)
150 constexpr
unsigned int numTotalSubRegions = 1 + 4 + 2 + 5;
154 TEST(RegionTests, RemoveResults)
191 size_t numRemovedResults = rootRegion.RemoveResults({ 0, 2, 4, 6, 8 });
192 EXPECT_EQ(numRemovedResults, 5u);
193 EXPECT_EQ(rootRegion.nresults(), 5u);
194 EXPECT_EQ(rootRegion.result(0)->origin(), &i1);
195 EXPECT_EQ(rootRegion.result(1)->origin(), &i3);
196 EXPECT_EQ(rootRegion.result(2)->origin(), &i5);
197 EXPECT_EQ(rootRegion.result(3)->origin(), &i7);
198 EXPECT_EQ(rootRegion.result(4)->origin(), &i9);
199 EXPECT_EQ(i0.nusers(), 0u);
200 EXPECT_EQ(i2.nusers(), 0u);
201 EXPECT_EQ(i4.nusers(), 0u);
202 EXPECT_EQ(i6.nusers(), 0u);
203 EXPECT_EQ(i8.nusers(), 0u);
207 numRemovedResults = rootRegion.RemoveResults({});
208 EXPECT_EQ(numRemovedResults, 0u);
209 EXPECT_EQ(rootRegion.nresults(), 5u);
213 numRemovedResults = rootRegion.RemoveResults({ 15 });
214 EXPECT_EQ(numRemovedResults, 0u);
215 EXPECT_EQ(rootRegion.nresults(), 5u);
219 numRemovedResults = rootRegion.RemoveResults({ 0, 1, 2, 3, 4 });
220 EXPECT_EQ(numRemovedResults, 5u);
221 EXPECT_EQ(rootRegion.nresults(), 0u);
222 EXPECT_EQ(i1.nusers(), 0u);
223 EXPECT_EQ(i3.nusers(), 0u);
224 EXPECT_EQ(i5.nusers(), 0u);
225 EXPECT_EQ(i7.nusers(), 0u);
226 EXPECT_EQ(i9.nusers(), 0u);
229 std::vector<size_t>({ 0, 2, 4, 6, 8, 0, 1, 2, 3, 4 }));
232 TEST(RegionTests, RemoveArguments)
254 { argument2, argument4, argument6 },
258 EXPECT_EQ(rootRegion.narguments(), 10u);
259 EXPECT_EQ(argument0->index(), 0u);
260 EXPECT_EQ(argument1->index(), 1u);
261 EXPECT_EQ(argument2->index(), 2u);
262 EXPECT_EQ(argument3->index(), 3u);
263 EXPECT_EQ(argument4->index(), 4u);
264 EXPECT_EQ(argument5->index(), 5u);
265 EXPECT_EQ(argument6->index(), 6u);
266 EXPECT_EQ(argument7->index(), 7u);
267 EXPECT_EQ(argument8->index(), 8u);
268 EXPECT_EQ(argument9->index(), 9u);
271 size_t numRemovedArguments = rootRegion.RemoveArguments({ 0, 2, 4, 6, 8 });
274 EXPECT_EQ(numRemovedArguments, 2u);
275 EXPECT_EQ(rootRegion.narguments(), 8u);
276 EXPECT_EQ(argument1->index(), 0u);
277 EXPECT_EQ(argument2->index(), 1u);
278 EXPECT_EQ(argument3->index(), 2u);
279 EXPECT_EQ(argument4->index(), 3u);
280 EXPECT_EQ(argument5->index(), 4u);
281 EXPECT_EQ(argument6->index(), 5u);
282 EXPECT_EQ(argument7->index(), 6u);
283 EXPECT_EQ(argument9->index(), 7u);
286 argument0 = argument1;
287 argument1 = argument2;
288 argument2 = argument3;
289 argument3 = argument4;
290 argument4 = argument5;
291 argument5 = argument6;
292 argument6 = argument7;
293 argument7 = argument9;
296 rootRegion.removeNode(node);
299 numRemovedArguments = rootRegion.RemoveArguments({ 0, 2, 4, 6 });
301 EXPECT_EQ(numRemovedArguments, 4u);
302 EXPECT_EQ(rootRegion.narguments(), 4u);
303 EXPECT_EQ(argument1->index(), 0u);
304 EXPECT_EQ(argument3->index(), 1u);
305 EXPECT_EQ(argument5->index(), 2u);
306 EXPECT_EQ(argument7->index(), 3u);
309 argument0 = argument1;
310 argument1 = argument3;
311 argument2 = argument5;
312 argument3 = argument7;
315 numRemovedArguments = rootRegion.RemoveArguments({});
316 EXPECT_EQ(numRemovedArguments, 0u);
317 EXPECT_EQ(rootRegion.narguments(), 4u);
318 EXPECT_EQ(argument0->index(), 0u);
319 EXPECT_EQ(argument1->index(), 1u);
320 EXPECT_EQ(argument2->index(), 2u);
321 EXPECT_EQ(argument3->index(), 3u);
324 numRemovedArguments = rootRegion.RemoveArguments({ 15 });
325 EXPECT_EQ(numRemovedArguments, 0u);
326 EXPECT_EQ(rootRegion.narguments(), 4u);
329 numRemovedArguments = rootRegion.RemoveArguments({ 0, 1, 2, 3 });
330 EXPECT_EQ(numRemovedArguments, 4u);
331 EXPECT_EQ(rootRegion.narguments(), 0u);
334 TEST(RegionTests, PruneArguments)
344 auto & argument0 = *structuralNode->addArguments(valueType).argument[0];
345 structuralNode->addArguments(valueType);
346 auto & argument2 = *structuralNode->addArguments(valueType).argument[0];
349 structuralNode->subregion(0),
350 { &argument0, &argument2 },
354 EXPECT_EQ(structuralNode->subregion(0)->narguments(), 3u);
356 size_t numRemovedArguments = structuralNode->subregion(0)->PruneArguments();
357 EXPECT_EQ(numRemovedArguments, 1u);
358 EXPECT_EQ(structuralNode->subregion(0)->narguments(), 2u);
359 EXPECT_EQ(argument0.index(), 0u);
360 EXPECT_EQ(argument2.index(), 1u);
362 structuralNode->subregion(0)->removeNode(node);
363 numRemovedArguments = structuralNode->subregion(0)->PruneArguments();
364 EXPECT_EQ(numRemovedArguments, 2u);
365 EXPECT_EQ(structuralNode->subregion(0)->narguments(), 0u);
368 TEST(RegionTests, ToTree_EmptyRvsdg)
377 std::cout << tree << std::flush;
380 EXPECT_EQ(tree,
"RootRegion\n");
383 TEST(RegionTests, ToTree_EmptyRvsdgWithAnnotations)
398 std::cout << tree << std::flush;
401 EXPECT_EQ(tree,
"RootRegion NumNodes:0\n");
404 TEST(RegionTests, ToTree_RvsdgWithStructuralNodes)
416 std::cout << tree << std::flush;
419 auto numLines = std::count(tree.begin(), tree.end(),
'\n');
422 EXPECT_EQ(numLines, 10);
425 auto lastLine = std::string(
"----Region[2]\n");
426 EXPECT_EQ(tree.compare(tree.size() - lastLine.size(), lastLine.size(), lastLine), 0);
429 TEST(RegionTests, ToTree_RvsdgWithStructuralNodesAndAnnotations)
438 auto subregion2 = structuralNode2->subregion(2);
443 Annotation(
"NumNodes",
static_cast<uint64_t
>(subregion2->numNodes())));
446 Annotation(
"NumArguments",
static_cast<uint64_t
>(subregion2->narguments())));
450 std::cout << tree << std::flush;
453 auto numLines = std::count(tree.begin(), tree.end(),
'\n');
456 EXPECT_EQ(numLines, 8);
459 auto lastLine = std::string(
"----Region[2] NumNodes:0 NumArguments:0\n");
460 EXPECT_EQ(tree.compare(tree.size() - lastLine.size(), lastLine.size(), lastLine), 0);
463 TEST(RegionTests, toJson_EmptyRvsdg)
472 std::cout << json << std::flush;
475 EXPECT_EQ(json,
"{}");
478 TEST(RegionTests, toJson_EmptyRvsdgWithAnnotations)
493 std::cout << json << std::flush;
496 EXPECT_EQ(json,
"{\"NumNodes\":0}");
499 TEST(RegionTests, toJson_RvsdgWithStructuralNodes)
513 structuralNode->subregion(1),
514 {
"RegionId", structuralNode->subregion(1)->getRegionId() });
518 std::cout << json << std::flush;
523 "{\"StructuralNodes\":[{\"DebugString\":\"TestStructuralOperation\",\"Subregions\":"
524 "[{\"StructuralNodes\":[{\"DebugString\":\"TestStructuralOperation\",\"Subregions\":"
525 "[{}]}]},{\"RegionId\":2,\"StructuralNodes\":[{\"DebugString\":"
526 "\"TestStructuralOperation\",\"Subregions\":[{}]},{\"DebugString\":"
527 "\"TestStructuralOperation\",\"Subregions\":[{},{},{}]}]}]}]}");
530 TEST(RegionTests, toJson_RvsdgWithStructuralNodesAndAnnotations)
539 auto subregion2 = structuralNode2->subregion(2);
544 Annotation(
"NumNodes",
static_cast<uint64_t
>(subregion2->numNodes())));
547 Annotation(
"NumArguments",
static_cast<uint64_t
>(subregion2->narguments())));
551 std::cout << json << std::flush;
556 "{\"StructuralNodes\":[{\"DebugString\":\"TestStructuralOperation\",\"Subregions\":"
557 "[{},{\"StructuralNodes\":[{\"DebugString\":\"TestStructuralOperation\",\"Subregions\""
558 ":[{},{},{\"NumNodes\":0,\"NumArguments\":0}]}]}]}]}");
561 TEST(RegionTests, BottomNodeTests)
573 EXPECT_TRUE(structuralNode->IsDead());
578 auto & output = structuralNode->addOutputOnly(valueType);
580 EXPECT_FALSE(structuralNode->IsDead());
586 EXPECT_TRUE(structuralNode->IsDead());
609 { node1->output(0), node2->output(0) },
618 EXPECT_EQ(depthMap.size(), 4u);
619 EXPECT_EQ(depthMap.at(node0), 0u);
620 EXPECT_EQ(depthMap.at(node1), 1u);
621 EXPECT_EQ(depthMap.at(node2), 0u);
622 EXPECT_EQ(depthMap.at(node3), 2u);
645 EXPECT_FALSE(
Region::isAncestor(*structuralNode1->subregion(0), *structuralNode1->subregion(0)));
648 EXPECT_FALSE(
Region::isAncestor(*structuralNode1->subregion(0), *structuralNode2->subregion(0)));
651 EXPECT_TRUE(
Region::isAncestor(*structuralNode3->subregion(0), *structuralNode1->subregion(0)));
652 EXPECT_TRUE(
Region::isAncestor(*structuralNode4->subregion(0), *structuralNode1->subregion(0)));
static bool Contains(const jlm::llvm::InterProceduralGraphModule &module, const std::string &)
TEST(RegionTests, IteratorRanges)
static GraphExport & Create(Output &origin, std::string name)
static GraphImport & Create(Graph &graph, std::shared_ptr< const rvsdg::Type > type, std::string name)
Region & GetRootRegion() const noexcept
const std::vector< size_t > & destroyedInputIndices() const noexcept
Represent acyclic RVSDG subgraphs.
size_t RemoveResults(const util::HashSet< size_t > &indices)
BottomNodeRange BottomNodes() noexcept
size_t numNodes() const noexcept
static std::string toJson(const Region ®ion, const util::AnnotationMap &annotationMap) noexcept
static std::string ToTree(const rvsdg::Region ®ion, const util::AnnotationMap &annotationMap) noexcept
size_t nresults() const noexcept
RegionArgument * argument(size_t index) const noexcept
bool IsRootRegion() const noexcept
static size_t NumRegions(const rvsdg::Region ®ion) noexcept
size_t numBottomNodes() const noexcept
static bool isAncestor(const rvsdg::Region ®ion, const rvsdg::Region &ancestor) noexcept
static Node * create(const std::shared_ptr< const Type > &operandType, std::shared_ptr< const Type > resultType, Output *op1, Output *op2)
static SimpleNode * createNode(Region *region, const std::vector< Output * > &operands, std::vector< std::shared_ptr< const Type >> resultTypes)
static TestStructuralNode * create(Region *parent, const size_t numSubregions)
static std::shared_ptr< const TestType > createValueType()
static Node * create(Region *, std::shared_ptr< const Type > operandType, Output *operand, std::shared_ptr< const Type > resultType)
void AddAnnotation(const void *key, Annotation annotation)
std::unordered_map< const Node *, size_t > computeDepthMap(const Region ®ion)