Jlm
Loading...
Searching...
No Matches
DifferencePropagationTests.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2024 HÃ¥vard Krogstie <krogstie.havard@gmail.com>
3 * See COPYING for terms of redistribution.
4 */
5
6#include <gtest/gtest.h>
7
11
12TEST(DifferencePropagationTests, TestTracksDifferences)
13{
14 using namespace jlm;
15 using namespace jlm::llvm::aa;
16
17 // Arrange
19 rvsdg.InitializeTest();
20
22 auto r0 = set.CreateRegisterPointerObject(rvsdg.GetAllocaOutput(0));
23 auto r1 = set.CreateRegisterPointerObject(rvsdg.GetAllocaOutput(1));
24 auto a0 = set.CreateAllocaMemoryObject(rvsdg.GetAllocaNode(0), true);
25 auto a1 = set.CreateAllocaMemoryObject(rvsdg.GetAllocaNode(1), true);
26 auto a2 = set.CreateAllocaMemoryObject(rvsdg.GetAllocaNode(2), true);
27 auto a3 = set.CreateAllocaMemoryObject(rvsdg.GetAllocaNode(3), true);
28
29 // Let r0 -> a0 and r0 -> a3 before difference tracking even begins
30 set.AddToPointsToSet(r0, a0);
31 set.AddToPointsToSet(r0, a3);
32
33 // Act
34 DifferencePropagation differencePropagation(set);
35 differencePropagation.Initialize();
36
37 // Assert
38 EXPECT_EQ(differencePropagation.GetNewPointees(r0), (util::HashSet{ a0, a3 }));
39
40 // Act 2 - add another pointer/pointee relation: r1 -> a1
41 differencePropagation.AddToPointsToSet(r1, a1);
42
43 // Assert that a1 is a new pointee of r1
44 EXPECT_EQ(differencePropagation.GetNewPointees(r1), util::HashSet{ a1 });
45
46 // Act 3 - clear difference tracking for r1
47 differencePropagation.ClearNewPointees(r1);
48
49 // Assert r1 no longer has any new pointees
50 EXPECT_TRUE(differencePropagation.GetNewPointees(r1).IsEmpty());
51 // r0 still has new pointees
52 EXPECT_FALSE(differencePropagation.GetNewPointees(r0).IsEmpty());
53
54 // Act 4 - add more pointees to r1,
55 bool new0 = differencePropagation.AddToPointsToSet(r1, a0);
56 bool new1 = differencePropagation.AddToPointsToSet(r1, a1); // not a new pointee
57 bool new2 = differencePropagation.AddToPointsToSet(r1, a2);
58
59 // Assert that only a0 and a2 were new
60 EXPECT_TRUE(new0 && !new1 && new2);
61 EXPECT_EQ(differencePropagation.GetNewPointees(r1), util::HashSet({ a0, a2 }));
62
63 // Act 5 - make r0 point to a superset of r1, making r0 now point to a0, a1, a2, a3
64 // First mark the existing pointees of r0 (a0 and a3) as seen
65 differencePropagation.ClearNewPointees(r0);
66 differencePropagation.MakePointsToSetSuperset(r0, r1);
67
68 // Assert that only a1 and a2 are new to r0, as it has already marked a0 and a3 as seen
69 EXPECT_EQ(differencePropagation.GetNewPointees(r0), util::HashSet({ a1, a2 }));
70
71 // Act 6 - give nodes r0 and r1 flags
74
75 // Assert that the flags are new, but only if they actually have the flag
76 EXPECT_TRUE(differencePropagation.PointeesEscapeIsNew(r0));
77 EXPECT_FALSE(differencePropagation.PointsToExternalIsNew(r0));
78 EXPECT_FALSE(differencePropagation.PointeesEscapeIsNew(r1));
79 EXPECT_TRUE(differencePropagation.PointsToExternalIsNew(r1));
80
81 // Act 7 - mark flags as seen
82 differencePropagation.MarkPointeesEscapeAsHandled(r0);
83 differencePropagation.MarkPointsToExternalAsHandled(r1);
84
85 // Assert that the flags are no longer new
86 EXPECT_FALSE(differencePropagation.PointeesEscapeIsNew(r0));
87 EXPECT_FALSE(differencePropagation.PointsToExternalIsNew(r1));
88
89 // Act 6 - unify 0 and 1
90 // After unification, any pointee or flag that is new to either node becomes new to the union
91 auto root = set.UnifyPointerObjects(r0, r1);
92 auto nonRoot = r0 + r1 - root;
93 differencePropagation.OnPointerObjectsUnified(root, nonRoot);
94
95 // Assert that all pointees that were new to either node, are also new to the root
96 // a0 and a2 were still marked as new to node r1 at the time of unification.
97 // a3 is not new to r0, but r1 has never seen it, so it must be regarded as new by the union.
98 util::HashSet<PointerObjectIndex> subset{ a0, a2, a3 };
99 EXPECT_TRUE(subset.IsSubsetOf(differencePropagation.GetNewPointees(root)));
100
101 // Neither flag has been seen by both nodes, so they are both new to the unification
102 EXPECT_TRUE(differencePropagation.PointeesEscapeIsNew(root));
103 EXPECT_TRUE(differencePropagation.PointsToExternalIsNew(root));
104}
TEST(DifferencePropagationTests, TestTracksDifferences)
RVSDG module with an arbitrary amount of alloca nodes.
const rvsdg::SimpleNode & GetAllocaNode(size_t index) const noexcept
const jlm::rvsdg::Output & GetAllocaOutput(size_t index) const noexcept
bool AddToPointsToSet(PointerObjectIndex pointer, PointerObjectIndex pointee)
bool PointeesEscapeIsNew(PointerObjectIndex index)
void OnPointerObjectsUnified(PointerObjectIndex root, PointerObjectIndex nonRoot)
bool PointsToExternalIsNew(PointerObjectIndex index)
const util::HashSet< PointerObjectIndex > & GetNewPointees(PointerObjectIndex index) const
void MarkPointsToExternalAsHandled(PointerObjectIndex index)
bool MakePointsToSetSuperset(PointerObjectIndex superset, PointerObjectIndex subset)
void MarkPointeesEscapeAsHandled(PointerObjectIndex index)
void ClearNewPointees(PointerObjectIndex index)
PointerObjectIndex UnifyPointerObjects(PointerObjectIndex object1, PointerObjectIndex object2)
PointerObjectIndex CreateRegisterPointerObject(const rvsdg::Output &rvsdgOutput)
bool AddToPointsToSet(PointerObjectIndex pointer, PointerObjectIndex pointee)
bool MarkAsPointeesEscaping(PointerObjectIndex index)
PointerObjectIndex CreateAllocaMemoryObject(const rvsdg::SimpleNode &allocaNode, bool canPoint)
bool MarkAsPointingToExternal(PointerObjectIndex index)
bool IsEmpty() const noexcept
Definition HashSet.hpp:198