Jlm
Loading...
Searching...
No Matches
LazyCycleDetectionTests.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2023, 2024 HÃ¥vard Krogstie <krogstie.havard@gmail.com>
3 * See COPYING for terms of redistribution.
4 */
5
6#include <gtest/gtest.h>
7
10#include <jlm/util/HashSet.hpp>
11
12#include <cassert>
13#include <vector>
14
15TEST(LazyCycleDetectionTests, TestUnifiesCycles)
16{
17 using namespace jlm;
18 using namespace jlm::llvm::aa;
19
20 // Arrange
22 for (int i = 0; i < 6; i++)
23 {
25 }
26
27 // Create a graph that looks like
28 // --> 1 --> 2 --> 3
29 // / |
30 // 0 |
31 // \ V
32 // --> 5 --> 4
33 std::vector<util::HashSet<PointerObjectIndex>> successors(set.NumPointerObjects());
34 successors[0].insert(1);
35 successors[1].insert(2);
36 successors[2].insert(3);
37 successors[2].insert(4);
38 successors[0].insert(5);
39 successors[5].insert(4);
40
41 auto GetSuccessors = [&](PointerObjectIndex i)
42 {
43 EXPECT_TRUE(set.IsUnificationRoot(i));
44 return successors[i].Items();
45 };
46
47 auto UnifyPointerObjects = [&](PointerObjectIndex a, PointerObjectIndex b)
48 {
49 EXPECT_TRUE(set.IsUnificationRoot(a));
50 EXPECT_TRUE(set.IsUnificationRoot(b));
51 EXPECT_NE(a, b);
52 auto newRoot = set.UnifyPointerObjects(a, b);
53 auto notRoot = a + b - newRoot;
54
55 successors[newRoot].UnionWith(successors[notRoot]);
56 return newRoot;
57 };
58
59 LazyCycleDetector lcd(set, GetSuccessors, UnifyPointerObjects);
60 lcd.Initialize();
61
62 // Act 1 - an edge that is not a part of a cycle
63 lcd.OnPropagatedNothing(0, 1);
64
65 // Assert that nothing happened
66 EXPECT_EQ(lcd.NumCycleDetectionAttempts(), 1u);
67 EXPECT_EQ(lcd.NumCyclesDetected(), 0u);
68 EXPECT_EQ(lcd.NumCycleUnifications(), 0u);
69
70 // Act 2 - Try the same edge again
71 lcd.OnPropagatedNothing(0, 1);
72
73 // Assert that the second attempt is ignored
74 EXPECT_EQ(lcd.NumCycleDetectionAttempts(), 1u);
75 EXPECT_EQ(lcd.NumCyclesDetected(), 0u);
76 EXPECT_EQ(lcd.NumCycleUnifications(), 0u);
77
78 // Act 3 - add the edge 3->1 that creates a cycle 3-1-2-3
79 successors[3].insert(1);
80 lcd.OnPropagatedNothing(3, 1);
81
82 // Assert that the cycle was found and unified
83 EXPECT_EQ(lcd.NumCycleDetectionAttempts(), 2u);
84 EXPECT_EQ(lcd.NumCyclesDetected(), 1u);
85 EXPECT_EQ(lcd.NumCycleUnifications(), 2u);
86 EXPECT_EQ(set.GetUnificationRoot(1), set.GetUnificationRoot(2));
87 EXPECT_EQ(set.GetUnificationRoot(1), set.GetUnificationRoot(3));
88
89 // Act 4 - add the edge 4 -> 0, creating two cycles 4-0-5-4 and 4-0-(1/2/3)-4
90 successors[4].insert(0);
91 lcd.OnPropagatedNothing(4, 0);
92
93 // Assert that both cycles were found.
94 // They are only counted as one cycle, but everything should be unified now
95 EXPECT_EQ(lcd.NumCyclesDetected(), 2u);
96 EXPECT_EQ(lcd.NumCycleUnifications(), set.NumPointerObjects() - 1);
97 for (PointerObjectIndex i = 1; i < set.NumPointerObjects(); i++)
98 {
99 EXPECT_EQ(set.GetUnificationRoot(0), set.GetUnificationRoot(i));
100 }
101}
TEST(LazyCycleDetectionTests, TestUnifiesCycles)
size_t NumCycleUnifications() const noexcept
size_t NumCyclesDetected() const noexcept
size_t NumCycleDetectionAttempts() const noexcept
std::optional< PointerObjectIndex > OnPropagatedNothing(PointerObjectIndex subset, PointerObjectIndex superset)
PointerObjectIndex UnifyPointerObjects(PointerObjectIndex object1, PointerObjectIndex object2)
PointerObjectIndex CreateDummyRegisterPointerObject()
PointerObjectIndex GetUnificationRoot(PointerObjectIndex index) const noexcept
bool IsUnificationRoot(PointerObjectIndex index) const noexcept
size_t NumPointerObjects() const noexcept
uint32_t PointerObjectIndex