| //===- StableFunctionMapTest.cpp ------------------------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/CGData/StableFunctionMap.h" |
| #include "gmock/gmock-matchers.h" |
| #include "gmock/gmock.h" |
| #include "gtest/gtest.h" |
| |
| using namespace llvm; |
| |
| namespace { |
| |
| using testing::Contains; |
| using testing::IsEmpty; |
| using testing::Key; |
| using testing::Not; |
| using testing::Pair; |
| using testing::SizeIs; |
| |
| TEST(StableFunctionMap, Name) { |
| StableFunctionMap Map; |
| EXPECT_TRUE(Map.empty()); |
| EXPECT_TRUE(Map.getNames().empty()); |
| unsigned ID1 = Map.getIdOrCreateForName("Func1"); |
| unsigned ID2 = Map.getIdOrCreateForName("Func2"); |
| unsigned ID3 = Map.getIdOrCreateForName("Func1"); |
| |
| EXPECT_THAT(Map.getNames(), SizeIs(2)); |
| // The different names should return different IDs. |
| EXPECT_NE(ID1, ID2); |
| // The same name should return the same ID. |
| EXPECT_EQ(ID1, ID3); |
| // The IDs should be valid. |
| EXPECT_EQ(*Map.getNameForId(ID1), "Func1"); |
| EXPECT_EQ(*Map.getNameForId(ID2), "Func2"); |
| } |
| |
| TEST(StableFunctionMap, Insert) { |
| StableFunctionMap Map; |
| |
| StableFunction Func1{1, "Func1", "Mod1", 2, {{{0, 1}, 3}}}; |
| StableFunction Func2{1, "Func2", "Mod1", 2, {{{0, 1}, 2}}}; |
| Map.insert(Func1); |
| Map.insert(Func2); |
| // We only have a unique hash, 1 |
| EXPECT_THAT(Map, SizeIs(1)); |
| // We have two functions with the same hash which are potentially mergeable. |
| EXPECT_EQ(Map.size(StableFunctionMap::SizeType::TotalFunctionCount), 2u); |
| EXPECT_EQ(Map.size(StableFunctionMap::SizeType::MergeableFunctionCount), 2u); |
| } |
| |
| TEST(StableFunctionMap, Merge) { |
| StableFunctionMap Map1; |
| StableFunction Func1{1, "Func1", "Mod1", 2, {{{0, 1}, 3}}}; |
| StableFunction Func2{1, "Func2", "Mod1", 2, {{{0, 1}, 2}}}; |
| StableFunction Func3{2, "Func3", "Mod1", 2, {{{1, 1}, 2}}}; |
| Map1.insert(Func1); |
| Map1.insert(Func2); |
| Map1.insert(Func3); |
| |
| StableFunctionMap Map2; |
| StableFunction Func4{1, "Func4", "Mod2", 2, {{{0, 1}, 4}}}; |
| StableFunction Func5{2, "Func5", "Mod2", 2, {{{1, 1}, 5}}}; |
| StableFunction Func6{3, "Func6", "Mod2", 2, {{{1, 1}, 6}}}; |
| Map2.insert(Func4); |
| Map2.insert(Func5); |
| Map2.insert(Func6); |
| |
| // Merge two maps. |
| Map1.merge(Map2); |
| |
| // We only have two unique hashes, 1, 2 and 3 |
| EXPECT_THAT(Map1, SizeIs(3)); |
| // We have total 6 functions. |
| EXPECT_EQ(Map1.size(StableFunctionMap::SizeType::TotalFunctionCount), 6u); |
| // We have 5 mergeable functions. Func6 only has a unique hash, 3. |
| EXPECT_EQ(Map1.size(StableFunctionMap::SizeType::MergeableFunctionCount), 5u); |
| } |
| |
| TEST(StableFunctionMap, Finalize1) { |
| StableFunctionMap Map; |
| StableFunction Func1{1, "Func1", "Mod1", 2, {{{0, 1}, 3}}}; |
| StableFunction Func2{1, "Func2", "Mod2", 3, {{{0, 1}, 2}}}; |
| Map.insert(Func1); |
| Map.insert(Func2); |
| |
| // Instruction count is mis-matched, so they're not mergeable. |
| Map.finalize(); |
| EXPECT_THAT(Map, IsEmpty()); |
| } |
| |
| TEST(StableFunctionMap, Finalize2) { |
| StableFunctionMap Map; |
| StableFunction Func1{1, "Func1", "Mod1", 2, {{{0, 1}, 3}}}; |
| StableFunction Func2{1, "Func2", "Mod2", 2, {{{0, 1}, 2}, {{1, 1}, 1}}}; |
| Map.insert(Func1); |
| Map.insert(Func2); |
| |
| // Operand map size is mis-matched, so they're not mergeable. |
| Map.finalize(); |
| EXPECT_THAT(Map, IsEmpty()); |
| } |
| |
| TEST(StableFunctionMap, Finalize3) { |
| StableFunctionMap Map; |
| StableFunction Func1{1, "Func1", "Mod1", 12, {{{0, 1}, 3}, {{1, 1}, 1}}}; |
| StableFunction Func2{1, "Func2", "Mod2", 12, {{{0, 1}, 2}, {{1, 1}, 1}}}; |
| Map.insert(Func1); |
| Map.insert(Func2); |
| |
| // The same operand entry is removed, which is redundant. |
| Map.finalize(); |
| auto &M = Map.getFunctionMap(); |
| EXPECT_THAT(M, SizeIs(1)); |
| auto &FuncEntries = M.begin()->second; |
| for (auto &FuncEntry : FuncEntries) { |
| EXPECT_THAT(*FuncEntry->IndexOperandHashMap, SizeIs(1)); |
| ASSERT_THAT(*FuncEntry->IndexOperandHashMap, |
| Not(Contains(Key(Pair(1, 1))))); |
| } |
| } |
| |
| } // end namespace |