xref: /llvm-project/llvm/unittests/CGData/StableFunctionMapTest.cpp (revision d23c5c2d6566fce4380cfa31d438422db19fbce9)
1 //===- StableFunctionMapTest.cpp ------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/CGData/StableFunctionMap.h"
10 #include "gmock/gmock-matchers.h"
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
13 
14 using namespace llvm;
15 
16 namespace {
17 
18 using testing::Contains;
19 using testing::IsEmpty;
20 using testing::Key;
21 using testing::Not;
22 using testing::Pair;
23 using testing::SizeIs;
24 
25 TEST(StableFunctionMap, Name) {
26   StableFunctionMap Map;
27   EXPECT_TRUE(Map.empty());
28   EXPECT_TRUE(Map.getNames().empty());
29   unsigned ID1 = Map.getIdOrCreateForName("Func1");
30   unsigned ID2 = Map.getIdOrCreateForName("Func2");
31   unsigned ID3 = Map.getIdOrCreateForName("Func1");
32 
33   EXPECT_THAT(Map.getNames(), SizeIs(2));
34   // The different names should return different IDs.
35   EXPECT_NE(ID1, ID2);
36   // The same name should return the same ID.
37   EXPECT_EQ(ID1, ID3);
38   // The IDs should be valid.
39   EXPECT_EQ(*Map.getNameForId(ID1), "Func1");
40   EXPECT_EQ(*Map.getNameForId(ID2), "Func2");
41 }
42 
43 TEST(StableFunctionMap, Insert) {
44   StableFunctionMap Map;
45 
46   StableFunction Func1{1, "Func1", "Mod1", 2, {{{0, 1}, 3}}};
47   StableFunction Func2{1, "Func2", "Mod1", 2, {{{0, 1}, 2}}};
48   Map.insert(Func1);
49   Map.insert(Func2);
50   // We only have a unique hash, 1
51   EXPECT_THAT(Map, SizeIs(1));
52   // We have two functions with the same hash which are potentially mergeable.
53   EXPECT_EQ(Map.size(StableFunctionMap::SizeType::TotalFunctionCount), 2u);
54   EXPECT_EQ(Map.size(StableFunctionMap::SizeType::MergeableFunctionCount), 2u);
55 }
56 
57 TEST(StableFunctionMap, Merge) {
58   StableFunctionMap Map1;
59   StableFunction Func1{1, "Func1", "Mod1", 2, {{{0, 1}, 3}}};
60   StableFunction Func2{1, "Func2", "Mod1", 2, {{{0, 1}, 2}}};
61   StableFunction Func3{2, "Func3", "Mod1", 2, {{{1, 1}, 2}}};
62   Map1.insert(Func1);
63   Map1.insert(Func2);
64   Map1.insert(Func3);
65 
66   StableFunctionMap Map2;
67   StableFunction Func4{1, "Func4", "Mod2", 2, {{{0, 1}, 4}}};
68   StableFunction Func5{2, "Func5", "Mod2", 2, {{{1, 1}, 5}}};
69   StableFunction Func6{3, "Func6", "Mod2", 2, {{{1, 1}, 6}}};
70   Map2.insert(Func4);
71   Map2.insert(Func5);
72   Map2.insert(Func6);
73 
74   // Merge two maps.
75   Map1.merge(Map2);
76 
77   // We only have two unique hashes, 1, 2 and 3
78   EXPECT_THAT(Map1, SizeIs(3));
79   // We have total 6 functions.
80   EXPECT_EQ(Map1.size(StableFunctionMap::SizeType::TotalFunctionCount), 6u);
81   // We have 5 mergeable functions. Func6 only has a unique hash, 3.
82   EXPECT_EQ(Map1.size(StableFunctionMap::SizeType::MergeableFunctionCount), 5u);
83 }
84 
85 TEST(StableFunctionMap, Finalize1) {
86   StableFunctionMap Map;
87   StableFunction Func1{1, "Func1", "Mod1", 2, {{{0, 1}, 3}}};
88   StableFunction Func2{1, "Func2", "Mod2", 3, {{{0, 1}, 2}}};
89   Map.insert(Func1);
90   Map.insert(Func2);
91 
92   // Instruction count is mis-matched, so they're not mergeable.
93   Map.finalize();
94   EXPECT_THAT(Map, IsEmpty());
95 }
96 
97 TEST(StableFunctionMap, Finalize2) {
98   StableFunctionMap Map;
99   StableFunction Func1{1, "Func1", "Mod1", 2, {{{0, 1}, 3}}};
100   StableFunction Func2{1, "Func2", "Mod2", 2, {{{0, 1}, 2}, {{1, 1}, 1}}};
101   Map.insert(Func1);
102   Map.insert(Func2);
103 
104   // Operand map size is mis-matched, so they're not mergeable.
105   Map.finalize();
106   EXPECT_THAT(Map, IsEmpty());
107 }
108 
109 TEST(StableFunctionMap, Finalize3) {
110   StableFunctionMap Map;
111   StableFunction Func1{1, "Func1", "Mod1", 12, {{{0, 1}, 3}, {{1, 1}, 1}}};
112   StableFunction Func2{1, "Func2", "Mod2", 12, {{{0, 1}, 2}, {{1, 1}, 1}}};
113   Map.insert(Func1);
114   Map.insert(Func2);
115 
116   // The same operand entry is removed, which is redundant.
117   Map.finalize();
118   auto &M = Map.getFunctionMap();
119   EXPECT_THAT(M, SizeIs(1));
120   auto &FuncEntries = M.begin()->second;
121   for (auto &FuncEntry : FuncEntries) {
122     EXPECT_THAT(*FuncEntry->IndexOperandHashMap, SizeIs(1));
123     ASSERT_THAT(*FuncEntry->IndexOperandHashMap,
124                 Not(Contains(Key(Pair(1, 1)))));
125   }
126 }
127 
128 } // end namespace
129