blob: 79f880e475c62a46dfa2701e8167686f1fa8b7ee [file] [log] [blame]
Eugene Zelenkoffec81c2015-11-04 22:32:32 +00001//===- unittest/ProfileData/InstrProfTest.cpp -------------------*- C++ -*-===//
Justin Bogner2b6c5372015-02-18 01:58:17 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Xinliang David Li59411db2016-01-20 01:26:34 +000010#include "llvm/IR/Function.h"
Xinliang David Li402477d2016-02-04 19:11:43 +000011#include "llvm/IR/IRBuilder.h"
Xinliang David Li59411db2016-01-20 01:26:34 +000012#include "llvm/IR/LLVMContext.h"
13#include "llvm/IR/Module.h"
Justin Bogner2b6c5372015-02-18 01:58:17 +000014#include "llvm/ProfileData/InstrProfReader.h"
15#include "llvm/ProfileData/InstrProfWriter.h"
Xinliang David Lie413f1a2015-12-31 07:57:16 +000016#include "llvm/Support/Compression.h"
David Blaikie94b98b22017-07-07 21:02:59 +000017#include "llvm/Testing/Support/Error.h"
18#include "llvm/Testing/Support/SupportHelpers.h"
Justin Bogner2b6c5372015-02-18 01:58:17 +000019#include "gtest/gtest.h"
Justin Bogner2b6c5372015-02-18 01:58:17 +000020#include <cstdarg>
21
22using namespace llvm;
23
David Blaikie94b98b22017-07-07 21:02:59 +000024LLVM_NODISCARD static ::testing::AssertionResult
25ErrorEquals(instrprof_error Expected, Error E) {
Vedant Kumar9152fd12016-05-19 03:54:45 +000026 instrprof_error Found;
27 std::string FoundMsg;
28 handleAllErrors(std::move(E), [&](const InstrProfError &IPE) {
29 Found = IPE.get();
30 FoundMsg = IPE.message();
31 });
Justin Bogner2b6c5372015-02-18 01:58:17 +000032 if (Expected == Found)
33 return ::testing::AssertionSuccess();
Vedant Kumar9152fd12016-05-19 03:54:45 +000034 return ::testing::AssertionFailure() << "error: " << FoundMsg << "\n";
Justin Bogner2b6c5372015-02-18 01:58:17 +000035}
36
37namespace {
38
39struct InstrProfTest : ::testing::Test {
40 InstrProfWriter Writer;
41 std::unique_ptr<IndexedInstrProfReader> Reader;
42
Vedant Kumar00dab222016-01-29 22:54:45 +000043 void SetUp() { Writer.setOutputSparse(false); }
44
Justin Bogner2b6c5372015-02-18 01:58:17 +000045 void readProfile(std::unique_ptr<MemoryBuffer> Profile) {
46 auto ReaderOrErr = IndexedInstrProfReader::create(std::move(Profile));
David Blaikie94b98b22017-07-07 21:02:59 +000047 EXPECT_THAT_ERROR(ReaderOrErr.takeError(), Succeeded());
Justin Bogner2b6c5372015-02-18 01:58:17 +000048 Reader = std::move(ReaderOrErr.get());
49 }
50};
51
Vedant Kumar00dab222016-01-29 22:54:45 +000052struct SparseInstrProfTest : public InstrProfTest {
53 void SetUp() { Writer.setOutputSparse(true); }
54};
55
56struct MaybeSparseInstrProfTest : public InstrProfTest,
57 public ::testing::WithParamInterface<bool> {
Vedant Kumar0259b7b2016-03-22 15:14:18 +000058 void SetUp() { Writer.setOutputSparse(GetParam()); }
Vedant Kumar00dab222016-01-29 22:54:45 +000059};
60
61TEST_P(MaybeSparseInstrProfTest, write_and_read_empty_profile) {
Justin Bogner2b6c5372015-02-18 01:58:17 +000062 auto Profile = Writer.writeBuffer();
63 readProfile(std::move(Profile));
64 ASSERT_TRUE(Reader->begin() == Reader->end());
65}
66
David Blaikie98cce002017-07-10 03:04:59 +000067static const auto Err = [](Error E) {
68 consumeError(std::move(E));
69 FAIL();
70};
71
Vedant Kumar00dab222016-01-29 22:54:45 +000072TEST_P(MaybeSparseInstrProfTest, write_and_read_one_function) {
David Blaikie98cce002017-07-10 03:04:59 +000073 Writer.addRecord({"foo", 0x1234, {1, 2, 3, 4}}, Err);
Justin Bogner2b6c5372015-02-18 01:58:17 +000074 auto Profile = Writer.writeBuffer();
75 readProfile(std::move(Profile));
76
77 auto I = Reader->begin(), E = Reader->end();
78 ASSERT_TRUE(I != E);
79 ASSERT_EQ(StringRef("foo"), I->Name);
80 ASSERT_EQ(0x1234U, I->Hash);
81 ASSERT_EQ(4U, I->Counts.size());
82 ASSERT_EQ(1U, I->Counts[0]);
83 ASSERT_EQ(2U, I->Counts[1]);
84 ASSERT_EQ(3U, I->Counts[2]);
85 ASSERT_EQ(4U, I->Counts[3]);
86 ASSERT_TRUE(++I == E);
87}
88
Vedant Kumar00dab222016-01-29 22:54:45 +000089TEST_P(MaybeSparseInstrProfTest, get_instr_prof_record) {
David Blaikie98cce002017-07-10 03:04:59 +000090 Writer.addRecord({"foo", 0x1234, {1, 2}}, Err);
91 Writer.addRecord({"foo", 0x1235, {3, 4}}, Err);
Xinliang David Li2004f002015-11-02 05:08:23 +000092 auto Profile = Writer.writeBuffer();
93 readProfile(std::move(Profile));
94
Vedant Kumar9152fd12016-05-19 03:54:45 +000095 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("foo", 0x1234);
David Blaikie94b98b22017-07-07 21:02:59 +000096 EXPECT_THAT_ERROR(R.takeError(), Succeeded());
David Blaikiefed557e2016-02-09 01:02:24 +000097 ASSERT_EQ(2U, R->Counts.size());
98 ASSERT_EQ(1U, R->Counts[0]);
99 ASSERT_EQ(2U, R->Counts[1]);
Xinliang David Li2004f002015-11-02 05:08:23 +0000100
101 R = Reader->getInstrProfRecord("foo", 0x1235);
David Blaikie94b98b22017-07-07 21:02:59 +0000102 EXPECT_THAT_ERROR(R.takeError(), Succeeded());
David Blaikiefed557e2016-02-09 01:02:24 +0000103 ASSERT_EQ(2U, R->Counts.size());
104 ASSERT_EQ(3U, R->Counts[0]);
105 ASSERT_EQ(4U, R->Counts[1]);
Xinliang David Li2004f002015-11-02 05:08:23 +0000106
107 R = Reader->getInstrProfRecord("foo", 0x5678);
Vedant Kumar9152fd12016-05-19 03:54:45 +0000108 ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, R.takeError()));
Xinliang David Li2004f002015-11-02 05:08:23 +0000109
110 R = Reader->getInstrProfRecord("bar", 0x1234);
Vedant Kumar9152fd12016-05-19 03:54:45 +0000111 ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, R.takeError()));
Xinliang David Li2004f002015-11-02 05:08:23 +0000112}
113
Vedant Kumar00dab222016-01-29 22:54:45 +0000114TEST_P(MaybeSparseInstrProfTest, get_function_counts) {
David Blaikie98cce002017-07-10 03:04:59 +0000115 Writer.addRecord({"foo", 0x1234, {1, 2}}, Err);
116 Writer.addRecord({"foo", 0x1235, {3, 4}}, Err);
Justin Bogner2b6c5372015-02-18 01:58:17 +0000117 auto Profile = Writer.writeBuffer();
118 readProfile(std::move(Profile));
119
120 std::vector<uint64_t> Counts;
David Blaikie94b98b22017-07-07 21:02:59 +0000121 EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1234, Counts),
122 Succeeded());
Justin Bogner2b6c5372015-02-18 01:58:17 +0000123 ASSERT_EQ(2U, Counts.size());
124 ASSERT_EQ(1U, Counts[0]);
125 ASSERT_EQ(2U, Counts[1]);
126
David Blaikie94b98b22017-07-07 21:02:59 +0000127 EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1235, Counts),
128 Succeeded());
Justin Bogner09829f42015-06-22 23:56:53 +0000129 ASSERT_EQ(2U, Counts.size());
130 ASSERT_EQ(3U, Counts[0]);
131 ASSERT_EQ(4U, Counts[1]);
132
Vedant Kumar9152fd12016-05-19 03:54:45 +0000133 Error E1 = Reader->getFunctionCounts("foo", 0x5678, Counts);
134 ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, std::move(E1)));
Justin Bogner2b6c5372015-02-18 01:58:17 +0000135
Vedant Kumar9152fd12016-05-19 03:54:45 +0000136 Error E2 = Reader->getFunctionCounts("bar", 0x1234, Counts);
137 ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, std::move(E2)));
Justin Bogner2b6c5372015-02-18 01:58:17 +0000138}
139
Xinliang David Li6c93ee82016-02-03 04:08:18 +0000140// Profile data is copied from general.proftext
141TEST_F(InstrProfTest, get_profile_summary) {
David Blaikie98cce002017-07-10 03:04:59 +0000142 Writer.addRecord({"func1", 0x1234, {97531}}, Err);
143 Writer.addRecord({"func2", 0x1234, {0, 0}}, Err);
144 Writer.addRecord(
145 {"func3",
146 0x1234,
147 {2305843009213693952, 1152921504606846976, 576460752303423488,
148 288230376151711744, 144115188075855872, 72057594037927936}},
149 Err);
150 Writer.addRecord({"func4", 0x1234, {0}}, Err);
Xinliang David Li6c93ee82016-02-03 04:08:18 +0000151 auto Profile = Writer.writeBuffer();
152 readProfile(std::move(Profile));
153
Easwaran Raman7cefdb82016-05-19 21:53:28 +0000154 auto VerifySummary = [](ProfileSummary &IPS) mutable {
155 ASSERT_EQ(ProfileSummary::PSK_Instr, IPS.getKind());
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000156 ASSERT_EQ(2305843009213693952U, IPS.getMaxFunctionCount());
Easwaran Raman7cefdb82016-05-19 21:53:28 +0000157 ASSERT_EQ(2305843009213693952U, IPS.getMaxCount());
158 ASSERT_EQ(10U, IPS.getNumCounts());
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000159 ASSERT_EQ(4539628424389557499U, IPS.getTotalCount());
160 std::vector<ProfileSummaryEntry> &Details = IPS.getDetailedSummary();
161 uint32_t Cutoff = 800000;
162 auto Predicate = [&Cutoff](const ProfileSummaryEntry &PE) {
163 return PE.Cutoff == Cutoff;
164 };
David Majnemer562e8292016-08-12 00:18:03 +0000165 auto EightyPerc = find_if(Details, Predicate);
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000166 Cutoff = 900000;
David Majnemer562e8292016-08-12 00:18:03 +0000167 auto NinetyPerc = find_if(Details, Predicate);
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000168 Cutoff = 950000;
David Majnemer562e8292016-08-12 00:18:03 +0000169 auto NinetyFivePerc = find_if(Details, Predicate);
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000170 Cutoff = 990000;
David Majnemer562e8292016-08-12 00:18:03 +0000171 auto NinetyNinePerc = find_if(Details, Predicate);
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000172 ASSERT_EQ(576460752303423488U, EightyPerc->MinCount);
173 ASSERT_EQ(288230376151711744U, NinetyPerc->MinCount);
174 ASSERT_EQ(288230376151711744U, NinetyFivePerc->MinCount);
175 ASSERT_EQ(72057594037927936U, NinetyNinePerc->MinCount);
Xinliang David Li6c93ee82016-02-03 04:08:18 +0000176 };
Easwaran Raman7cefdb82016-05-19 21:53:28 +0000177 ProfileSummary &PS = Reader->getSummary();
Easwaran Ramanf9709ee2016-03-14 22:23:28 +0000178 VerifySummary(PS);
Easwaran Raman26628d32016-03-18 21:29:30 +0000179
180 // Test that conversion of summary to and from Metadata works.
Mehdi Amini03b42e42016-04-14 21:59:01 +0000181 LLVMContext Context;
182 Metadata *MD = PS.getMD(Context);
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000183 ASSERT_TRUE(MD);
184 ProfileSummary *PSFromMD = ProfileSummary::getFromMD(MD);
185 ASSERT_TRUE(PSFromMD);
Easwaran Raman7cefdb82016-05-19 21:53:28 +0000186 VerifySummary(*PSFromMD);
187 delete PSFromMD;
Easwaran Raman26628d32016-03-18 21:29:30 +0000188
189 // Test that summary can be attached to and read back from module.
Mehdi Amini03b42e42016-04-14 21:59:01 +0000190 Module M("my_module", Context);
Easwaran Raman26628d32016-03-18 21:29:30 +0000191 M.setProfileSummary(MD);
192 MD = M.getProfileSummary();
193 ASSERT_TRUE(MD);
194 PSFromMD = ProfileSummary::getFromMD(MD);
195 ASSERT_TRUE(PSFromMD);
Easwaran Raman7cefdb82016-05-19 21:53:28 +0000196 VerifySummary(*PSFromMD);
197 delete PSFromMD;
Xinliang David Li6c93ee82016-02-03 04:08:18 +0000198}
199
Vedant Kumare3a0bf52016-07-19 01:17:20 +0000200TEST_F(InstrProfTest, test_writer_merge) {
David Blaikie98cce002017-07-10 03:04:59 +0000201 Writer.addRecord({"func1", 0x1234, {42}}, Err);
Vedant Kumare3a0bf52016-07-19 01:17:20 +0000202
203 InstrProfWriter Writer2;
David Blaikie98cce002017-07-10 03:04:59 +0000204 Writer2.addRecord({"func2", 0x1234, {0, 0}}, Err);
Vedant Kumare3a0bf52016-07-19 01:17:20 +0000205
David Blaikie98cce002017-07-10 03:04:59 +0000206 Writer.mergeRecordsFromWriter(std::move(Writer2), Err);
Vedant Kumare3a0bf52016-07-19 01:17:20 +0000207
208 auto Profile = Writer.writeBuffer();
209 readProfile(std::move(Profile));
210
211 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("func1", 0x1234);
David Blaikie94b98b22017-07-07 21:02:59 +0000212 EXPECT_THAT_ERROR(R.takeError(), Succeeded());
Vedant Kumare3a0bf52016-07-19 01:17:20 +0000213 ASSERT_EQ(1U, R->Counts.size());
214 ASSERT_EQ(42U, R->Counts[0]);
215
216 R = Reader->getInstrProfRecord("func2", 0x1234);
David Blaikie94b98b22017-07-07 21:02:59 +0000217 EXPECT_THAT_ERROR(R.takeError(), Succeeded());
Vedant Kumare3a0bf52016-07-19 01:17:20 +0000218 ASSERT_EQ(2U, R->Counts.size());
219 ASSERT_EQ(0U, R->Counts[0]);
220 ASSERT_EQ(0U, R->Counts[1]);
221}
222
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000223static const char callee1[] = "callee1";
224static const char callee2[] = "callee2";
225static const char callee3[] = "callee3";
226static const char callee4[] = "callee4";
227static const char callee5[] = "callee5";
228static const char callee6[] = "callee6";
229
Vedant Kumar00dab222016-01-29 22:54:45 +0000230TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write) {
David Blaikiecf9d52c2017-07-06 19:00:12 +0000231 NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
Xinliang David Li2004f002015-11-02 05:08:23 +0000232
233 // 4 value sites.
234 Record1.reserveSites(IPVK_IndirectCallTarget, 4);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000235 InstrProfValueData VD0[] = {
236 {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000237 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
Xinliang David Liee415892015-11-10 00:24:45 +0000238 // No value profile data at the second site.
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000239 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000240 InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000241 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000242 InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000243 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000244
David Blaikie98cce002017-07-10 03:04:59 +0000245 Writer.addRecord(std::move(Record1), Err);
246 Writer.addRecord({"callee1", 0x1235, {3, 4}}, Err);
247 Writer.addRecord({"callee2", 0x1235, {3, 4}}, Err);
248 Writer.addRecord({"callee3", 0x1235, {3, 4}}, Err);
Xinliang David Li2004f002015-11-02 05:08:23 +0000249 auto Profile = Writer.writeBuffer();
250 readProfile(std::move(Profile));
251
Vedant Kumar9152fd12016-05-19 03:54:45 +0000252 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
David Blaikie94b98b22017-07-07 21:02:59 +0000253 EXPECT_THAT_ERROR(R.takeError(), Succeeded());
David Blaikiefed557e2016-02-09 01:02:24 +0000254 ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
255 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
256 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
257 ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
258 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
Xinliang David Li2004f002015-11-02 05:08:23 +0000259
Xinliang David Li1e4c8092016-02-04 05:29:51 +0000260 uint64_t TotalC;
Xinliang David Li2004f002015-11-02 05:08:23 +0000261 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000262 R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000263
264 ASSERT_EQ(3U, VD[0].Count);
265 ASSERT_EQ(2U, VD[1].Count);
266 ASSERT_EQ(1U, VD[2].Count);
Xinliang David Li1e4c8092016-02-04 05:29:51 +0000267 ASSERT_EQ(6U, TotalC);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000268
269 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
270 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
271 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
272}
273
Xinliang David Li402477d2016-02-04 19:11:43 +0000274TEST_P(MaybeSparseInstrProfTest, annotate_vp_data) {
David Blaikiecf9d52c2017-07-06 19:00:12 +0000275 NamedInstrProfRecord Record("caller", 0x1234, {1, 2});
Xinliang David Li402477d2016-02-04 19:11:43 +0000276 Record.reserveSites(IPVK_IndirectCallTarget, 1);
Rong Xu69683f12016-02-10 22:19:43 +0000277 InstrProfValueData VD0[] = {{1000, 1}, {2000, 2}, {3000, 3}, {5000, 5},
278 {4000, 4}, {6000, 6}};
279 Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 6, nullptr);
David Blaikie98cce002017-07-10 03:04:59 +0000280 Writer.addRecord(std::move(Record), Err);
Xinliang David Li402477d2016-02-04 19:11:43 +0000281 auto Profile = Writer.writeBuffer();
282 readProfile(std::move(Profile));
Vedant Kumar9152fd12016-05-19 03:54:45 +0000283 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
David Blaikie94b98b22017-07-07 21:02:59 +0000284 EXPECT_THAT_ERROR(R.takeError(), Succeeded());
Xinliang David Li402477d2016-02-04 19:11:43 +0000285
286 LLVMContext Ctx;
287 std::unique_ptr<Module> M(new Module("MyModule", Ctx));
288 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
289 /*isVarArg=*/false);
290 Function *F =
291 Function::Create(FTy, Function::ExternalLinkage, "caller", M.get());
292 BasicBlock *BB = BasicBlock::Create(Ctx, "", F);
293
294 IRBuilder<> Builder(BB);
295 BasicBlock *TBB = BasicBlock::Create(Ctx, "", F);
296 BasicBlock *FBB = BasicBlock::Create(Ctx, "", F);
297
298 // Use branch instruction to annotate with value profile data for simplicity
299 Instruction *Inst = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
300 Instruction *Inst2 = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
David Blaikiefed557e2016-02-09 01:02:24 +0000301 annotateValueSite(*M, *Inst, R.get(), IPVK_IndirectCallTarget, 0);
Xinliang David Li402477d2016-02-04 19:11:43 +0000302
303 InstrProfValueData ValueData[5];
304 uint32_t N;
305 uint64_t T;
306 bool Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
307 ValueData, N, T);
308 ASSERT_TRUE(Res);
309 ASSERT_EQ(3U, N);
Rong Xu69683f12016-02-10 22:19:43 +0000310 ASSERT_EQ(21U, T);
Xinliang David Li402477d2016-02-04 19:11:43 +0000311 // The result should be sorted already:
Rong Xu69683f12016-02-10 22:19:43 +0000312 ASSERT_EQ(6000U, ValueData[0].Value);
313 ASSERT_EQ(6U, ValueData[0].Count);
314 ASSERT_EQ(5000U, ValueData[1].Value);
315 ASSERT_EQ(5U, ValueData[1].Count);
316 ASSERT_EQ(4000U, ValueData[2].Value);
317 ASSERT_EQ(4U, ValueData[2].Count);
Xinliang David Li402477d2016-02-04 19:11:43 +0000318 Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 1, ValueData,
319 N, T);
320 ASSERT_TRUE(Res);
321 ASSERT_EQ(1U, N);
Rong Xu69683f12016-02-10 22:19:43 +0000322 ASSERT_EQ(21U, T);
Xinliang David Li402477d2016-02-04 19:11:43 +0000323
324 Res = getValueProfDataFromInst(*Inst2, IPVK_IndirectCallTarget, 5, ValueData,
325 N, T);
326 ASSERT_FALSE(Res);
Rong Xu69683f12016-02-10 22:19:43 +0000327
328 // Remove the MD_prof metadata
329 Inst->setMetadata(LLVMContext::MD_prof, 0);
330 // Annotate 5 records this time.
331 annotateValueSite(*M, *Inst, R.get(), IPVK_IndirectCallTarget, 0, 5);
332 Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
333 ValueData, N, T);
334 ASSERT_TRUE(Res);
335 ASSERT_EQ(5U, N);
336 ASSERT_EQ(21U, T);
337 ASSERT_EQ(6000U, ValueData[0].Value);
338 ASSERT_EQ(6U, ValueData[0].Count);
339 ASSERT_EQ(5000U, ValueData[1].Value);
340 ASSERT_EQ(5U, ValueData[1].Count);
341 ASSERT_EQ(4000U, ValueData[2].Value);
342 ASSERT_EQ(4U, ValueData[2].Count);
343 ASSERT_EQ(3000U, ValueData[3].Value);
344 ASSERT_EQ(3U, ValueData[3].Count);
345 ASSERT_EQ(2000U, ValueData[4].Value);
346 ASSERT_EQ(2U, ValueData[4].Count);
Rong Xubb494902016-02-12 21:36:17 +0000347
348 // Remove the MD_prof metadata
349 Inst->setMetadata(LLVMContext::MD_prof, 0);
350 // Annotate with 4 records.
351 InstrProfValueData VD0Sorted[] = {{1000, 6}, {2000, 5}, {3000, 4}, {4000, 3},
352 {5000, 2}, {6000, 1}};
Rong Xu311ada12016-03-30 16:56:31 +0000353 annotateValueSite(*M, *Inst, makeArrayRef(VD0Sorted).slice(2), 10,
354 IPVK_IndirectCallTarget, 5);
Rong Xubb494902016-02-12 21:36:17 +0000355 Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
356 ValueData, N, T);
357 ASSERT_TRUE(Res);
358 ASSERT_EQ(4U, N);
359 ASSERT_EQ(10U, T);
360 ASSERT_EQ(3000U, ValueData[0].Value);
361 ASSERT_EQ(4U, ValueData[0].Count);
362 ASSERT_EQ(4000U, ValueData[1].Value);
363 ASSERT_EQ(3U, ValueData[1].Count);
364 ASSERT_EQ(5000U, ValueData[2].Value);
365 ASSERT_EQ(2U, ValueData[2].Count);
366 ASSERT_EQ(6000U, ValueData[3].Value);
367 ASSERT_EQ(1U, ValueData[3].Count);
Xinliang David Li402477d2016-02-04 19:11:43 +0000368}
369
Vedant Kumar00dab222016-01-29 22:54:45 +0000370TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_with_weight) {
David Blaikiecf9d52c2017-07-06 19:00:12 +0000371 NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000372
373 // 4 value sites.
374 Record1.reserveSites(IPVK_IndirectCallTarget, 4);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000375 InstrProfValueData VD0[] = {
376 {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000377 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
378 // No value profile data at the second site.
379 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000380 InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000381 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000382 InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000383 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
384
David Blaikie98cce002017-07-10 03:04:59 +0000385 Writer.addRecord(std::move(Record1), 10, Err);
386 Writer.addRecord({"callee1", 0x1235, {3, 4}}, Err);
387 Writer.addRecord({"callee2", 0x1235, {3, 4}}, Err);
388 Writer.addRecord({"callee3", 0x1235, {3, 4}}, Err);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000389 auto Profile = Writer.writeBuffer();
390 readProfile(std::move(Profile));
391
Vedant Kumar9152fd12016-05-19 03:54:45 +0000392 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
David Blaikie94b98b22017-07-07 21:02:59 +0000393 EXPECT_THAT_ERROR(R.takeError(), Succeeded());
David Blaikiefed557e2016-02-09 01:02:24 +0000394 ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
395 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
396 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
397 ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
398 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000399
Xinliang David Li1e4c8092016-02-04 05:29:51 +0000400 uint64_t TotalC;
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000401 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000402 R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000403 ASSERT_EQ(30U, VD[0].Count);
404 ASSERT_EQ(20U, VD[1].Count);
405 ASSERT_EQ(10U, VD[2].Count);
Xinliang David Li1e4c8092016-02-04 05:29:51 +0000406 ASSERT_EQ(60U, TotalC);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000407
Xinliang David Li2004f002015-11-02 05:08:23 +0000408 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
409 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
410 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
411}
412
Vedant Kumar00dab222016-01-29 22:54:45 +0000413TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_big_endian) {
David Blaikiecf9d52c2017-07-06 19:00:12 +0000414 NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
Xinliang David Li46ad3632016-01-22 19:53:31 +0000415
416 // 4 value sites.
417 Record1.reserveSites(IPVK_IndirectCallTarget, 4);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000418 InstrProfValueData VD0[] = {
419 {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
Xinliang David Li46ad3632016-01-22 19:53:31 +0000420 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
421 // No value profile data at the second site.
422 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000423 InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
Xinliang David Li46ad3632016-01-22 19:53:31 +0000424 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000425 InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
Xinliang David Li46ad3632016-01-22 19:53:31 +0000426 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
427
David Blaikie98cce002017-07-10 03:04:59 +0000428 Writer.addRecord(std::move(Record1), Err);
429 Writer.addRecord({"callee1", 0x1235, {3, 4}}, Err);
430 Writer.addRecord({"callee2", 0x1235, {3, 4}}, Err);
431 Writer.addRecord({"callee3", 0x1235, {3, 4}}, Err);
Xinliang David Li46ad3632016-01-22 19:53:31 +0000432
433 // Set big endian output.
434 Writer.setValueProfDataEndianness(support::big);
435
436 auto Profile = Writer.writeBuffer();
437 readProfile(std::move(Profile));
438
439 // Set big endian input.
440 Reader->setValueProfDataEndianness(support::big);
441
Vedant Kumar9152fd12016-05-19 03:54:45 +0000442 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
David Blaikie94b98b22017-07-07 21:02:59 +0000443 EXPECT_THAT_ERROR(R.takeError(), Succeeded());
David Blaikiefed557e2016-02-09 01:02:24 +0000444 ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
445 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
446 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
447 ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
448 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
Xinliang David Li46ad3632016-01-22 19:53:31 +0000449
450 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000451 R->getValueForSite(IPVK_IndirectCallTarget, 0);
Xinliang David Li46ad3632016-01-22 19:53:31 +0000452 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
453 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
454 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
455
456 // Restore little endian default:
457 Writer.setValueProfDataEndianness(support::little);
458}
459
Vedant Kumar00dab222016-01-29 22:54:45 +0000460TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge1) {
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000461 static const char caller[] = "caller";
David Blaikiecf9d52c2017-07-06 19:00:12 +0000462 NamedInstrProfRecord Record11(caller, 0x1234, {1, 2});
463 NamedInstrProfRecord Record12(caller, 0x1234, {1, 2});
Xinliang David Li2004f002015-11-02 05:08:23 +0000464
465 // 5 value sites.
466 Record11.reserveSites(IPVK_IndirectCallTarget, 5);
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000467 InstrProfValueData VD0[] = {{uint64_t(callee1), 1},
468 {uint64_t(callee2), 2},
469 {uint64_t(callee3), 3},
470 {uint64_t(callee4), 4}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000471 Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 4, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000472
Xinliang David Li872df222016-01-08 06:54:27 +0000473 // No value profile data at the second site.
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000474 Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000475
Xinliang David Li872df222016-01-08 06:54:27 +0000476 InstrProfValueData VD2[] = {
477 {uint64_t(callee1), 1}, {uint64_t(callee2), 2}, {uint64_t(callee3), 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000478 Record11.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000479
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000480 InstrProfValueData VD3[] = {{uint64_t(callee1), 1}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000481 Record11.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000482
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000483 InstrProfValueData VD4[] = {{uint64_t(callee1), 1},
484 {uint64_t(callee2), 2},
485 {uint64_t(callee3), 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000486 Record11.addValueData(IPVK_IndirectCallTarget, 4, VD4, 3, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000487
David Majnemer68318e02016-04-22 06:37:48 +0000488 // A different record for the same caller.
Xinliang David Li2004f002015-11-02 05:08:23 +0000489 Record12.reserveSites(IPVK_IndirectCallTarget, 5);
Xinliang David Li872df222016-01-08 06:54:27 +0000490 InstrProfValueData VD02[] = {{uint64_t(callee2), 5}, {uint64_t(callee3), 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000491 Record12.addValueData(IPVK_IndirectCallTarget, 0, VD02, 2, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000492
Xinliang David Li872df222016-01-08 06:54:27 +0000493 // No value profile data at the second site.
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000494 Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000495
Xinliang David Li872df222016-01-08 06:54:27 +0000496 InstrProfValueData VD22[] = {
497 {uint64_t(callee2), 1}, {uint64_t(callee3), 3}, {uint64_t(callee4), 4}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000498 Record12.addValueData(IPVK_IndirectCallTarget, 2, VD22, 3, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000499
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000500 Record12.addValueData(IPVK_IndirectCallTarget, 3, nullptr, 0, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000501
Xinliang David Li46ad3632016-01-22 19:53:31 +0000502 InstrProfValueData VD42[] = {{uint64_t(callee1), 1},
503 {uint64_t(callee2), 2},
504 {uint64_t(callee3), 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000505 Record12.addValueData(IPVK_IndirectCallTarget, 4, VD42, 3, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000506
David Blaikie98cce002017-07-10 03:04:59 +0000507 Writer.addRecord(std::move(Record11), Err);
Xinliang David Li2004f002015-11-02 05:08:23 +0000508 // Merge profile data.
David Blaikie98cce002017-07-10 03:04:59 +0000509 Writer.addRecord(std::move(Record12), Err);
Xinliang David Li2004f002015-11-02 05:08:23 +0000510
David Blaikie98cce002017-07-10 03:04:59 +0000511 Writer.addRecord({callee1, 0x1235, {3, 4}}, Err);
512 Writer.addRecord({callee2, 0x1235, {3, 4}}, Err);
513 Writer.addRecord({callee3, 0x1235, {3, 4}}, Err);
514 Writer.addRecord({callee3, 0x1235, {3, 4}}, Err);
515 Writer.addRecord({callee4, 0x1235, {3, 5}}, Err);
Xinliang David Li2004f002015-11-02 05:08:23 +0000516 auto Profile = Writer.writeBuffer();
517 readProfile(std::move(Profile));
518
Vedant Kumar9152fd12016-05-19 03:54:45 +0000519 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
David Blaikie94b98b22017-07-07 21:02:59 +0000520 EXPECT_THAT_ERROR(R.takeError(), Succeeded());
David Blaikiefed557e2016-02-09 01:02:24 +0000521 ASSERT_EQ(5U, R->getNumValueSites(IPVK_IndirectCallTarget));
522 ASSERT_EQ(4U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
523 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
524 ASSERT_EQ(4U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
525 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
526 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 4));
Xinliang David Li2004f002015-11-02 05:08:23 +0000527
528 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000529 R->getValueForSite(IPVK_IndirectCallTarget, 0);
Xinliang David Li2004f002015-11-02 05:08:23 +0000530 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee2"));
531 ASSERT_EQ(7U, VD[0].Count);
532 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee3"));
533 ASSERT_EQ(6U, VD[1].Count);
534 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee4"));
535 ASSERT_EQ(4U, VD[2].Count);
536 ASSERT_EQ(StringRef((const char *)VD[3].Value, 7), StringRef("callee1"));
537 ASSERT_EQ(1U, VD[3].Count);
538
539 std::unique_ptr<InstrProfValueData[]> VD_2(
David Blaikiefed557e2016-02-09 01:02:24 +0000540 R->getValueForSite(IPVK_IndirectCallTarget, 2));
Xinliang David Li2004f002015-11-02 05:08:23 +0000541 ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee3"));
542 ASSERT_EQ(6U, VD_2[0].Count);
543 ASSERT_EQ(StringRef((const char *)VD_2[1].Value, 7), StringRef("callee4"));
544 ASSERT_EQ(4U, VD_2[1].Count);
545 ASSERT_EQ(StringRef((const char *)VD_2[2].Value, 7), StringRef("callee2"));
546 ASSERT_EQ(3U, VD_2[2].Count);
547 ASSERT_EQ(StringRef((const char *)VD_2[3].Value, 7), StringRef("callee1"));
548 ASSERT_EQ(1U, VD_2[3].Count);
549
550 std::unique_ptr<InstrProfValueData[]> VD_3(
David Blaikiefed557e2016-02-09 01:02:24 +0000551 R->getValueForSite(IPVK_IndirectCallTarget, 3));
Xinliang David Li2004f002015-11-02 05:08:23 +0000552 ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee1"));
553 ASSERT_EQ(1U, VD_3[0].Count);
554
555 std::unique_ptr<InstrProfValueData[]> VD_4(
David Blaikiefed557e2016-02-09 01:02:24 +0000556 R->getValueForSite(IPVK_IndirectCallTarget, 4));
Xinliang David Li2004f002015-11-02 05:08:23 +0000557 ASSERT_EQ(StringRef((const char *)VD_4[0].Value, 7), StringRef("callee3"));
558 ASSERT_EQ(6U, VD_4[0].Count);
559 ASSERT_EQ(StringRef((const char *)VD_4[1].Value, 7), StringRef("callee2"));
560 ASSERT_EQ(4U, VD_4[1].Count);
561 ASSERT_EQ(StringRef((const char *)VD_4[2].Value, 7), StringRef("callee1"));
562 ASSERT_EQ(2U, VD_4[2].Count);
563}
564
Vedant Kumar00dab222016-01-29 22:54:45 +0000565TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge1_saturation) {
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000566 static const char bar[] = "bar";
567
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000568 const uint64_t Max = std::numeric_limits<uint64_t>::max();
569
David Blaikie98cce002017-07-10 03:04:59 +0000570 instrprof_error Result;
571 auto Err = [&](Error E) { Result = InstrProfError::take(std::move(E)); };
572 Result = instrprof_error::success;
573 Writer.addRecord({"foo", 0x1234, {1}}, Err);
574 ASSERT_EQ(Result, instrprof_error::success);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000575
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000576 // Verify counter overflow.
David Blaikie98cce002017-07-10 03:04:59 +0000577 Result = instrprof_error::success;
578 Writer.addRecord({"foo", 0x1234, {Max}}, Err);
579 ASSERT_EQ(Result, instrprof_error::counter_overflow);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000580
David Blaikie98cce002017-07-10 03:04:59 +0000581 Result = instrprof_error::success;
582 Writer.addRecord({bar, 0x9012, {8}}, Err);
583 ASSERT_EQ(Result, instrprof_error::success);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000584
David Blaikiecf9d52c2017-07-06 19:00:12 +0000585 NamedInstrProfRecord Record4("baz", 0x5678, {3, 4});
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000586 Record4.reserveSites(IPVK_IndirectCallTarget, 1);
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000587 InstrProfValueData VD4[] = {{uint64_t(bar), 1}};
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000588 Record4.addValueData(IPVK_IndirectCallTarget, 0, VD4, 1, nullptr);
David Blaikie98cce002017-07-10 03:04:59 +0000589 Result = instrprof_error::success;
590 Writer.addRecord(std::move(Record4), Err);
591 ASSERT_EQ(Result, instrprof_error::success);
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000592
593 // Verify value data counter overflow.
David Blaikiecf9d52c2017-07-06 19:00:12 +0000594 NamedInstrProfRecord Record5("baz", 0x5678, {5, 6});
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000595 Record5.reserveSites(IPVK_IndirectCallTarget, 1);
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000596 InstrProfValueData VD5[] = {{uint64_t(bar), Max}};
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000597 Record5.addValueData(IPVK_IndirectCallTarget, 0, VD5, 1, nullptr);
David Blaikie98cce002017-07-10 03:04:59 +0000598 Result = instrprof_error::success;
599 Writer.addRecord(std::move(Record5), Err);
600 ASSERT_EQ(Result, instrprof_error::counter_overflow);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000601
602 auto Profile = Writer.writeBuffer();
603 readProfile(std::move(Profile));
604
605 // Verify saturation of counts.
Vedant Kumar9152fd12016-05-19 03:54:45 +0000606 Expected<InstrProfRecord> ReadRecord1 =
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000607 Reader->getInstrProfRecord("foo", 0x1234);
David Blaikie94b98b22017-07-07 21:02:59 +0000608 EXPECT_THAT_ERROR(ReadRecord1.takeError(), Succeeded());
David Blaikiefed557e2016-02-09 01:02:24 +0000609 ASSERT_EQ(Max, ReadRecord1->Counts[0]);
Nathan Slingerlandaa5702d2015-12-02 18:19:24 +0000610
Vedant Kumar9152fd12016-05-19 03:54:45 +0000611 Expected<InstrProfRecord> ReadRecord2 =
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000612 Reader->getInstrProfRecord("baz", 0x5678);
Vedant Kumar9152fd12016-05-19 03:54:45 +0000613 ASSERT_TRUE(bool(ReadRecord2));
David Blaikiefed557e2016-02-09 01:02:24 +0000614 ASSERT_EQ(1U, ReadRecord2->getNumValueSites(IPVK_IndirectCallTarget));
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000615 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000616 ReadRecord2->getValueForSite(IPVK_IndirectCallTarget, 0);
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000617 ASSERT_EQ(StringRef("bar"), StringRef((const char *)VD[0].Value, 3));
618 ASSERT_EQ(Max, VD[0].Count);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000619}
620
Xinliang David Li872df222016-01-08 06:54:27 +0000621// This test tests that when there are too many values
622// for a given site, the merged results are properly
623// truncated.
Vedant Kumar00dab222016-01-29 22:54:45 +0000624TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge_site_trunc) {
Xinliang David Li872df222016-01-08 06:54:27 +0000625 static const char caller[] = "caller";
626
David Blaikiecf9d52c2017-07-06 19:00:12 +0000627 NamedInstrProfRecord Record11(caller, 0x1234, {1, 2});
628 NamedInstrProfRecord Record12(caller, 0x1234, {1, 2});
Xinliang David Li872df222016-01-08 06:54:27 +0000629
630 // 2 value sites.
631 Record11.reserveSites(IPVK_IndirectCallTarget, 2);
632 InstrProfValueData VD0[255];
633 for (int I = 0; I < 255; I++) {
634 VD0[I].Value = 2 * I;
635 VD0[I].Count = 2 * I + 1000;
636 }
637
638 Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 255, nullptr);
639 Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
640
641 Record12.reserveSites(IPVK_IndirectCallTarget, 2);
642 InstrProfValueData VD1[255];
643 for (int I = 0; I < 255; I++) {
644 VD1[I].Value = 2 * I + 1;
645 VD1[I].Count = 2 * I + 1001;
646 }
647
648 Record12.addValueData(IPVK_IndirectCallTarget, 0, VD1, 255, nullptr);
649 Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
650
David Blaikie98cce002017-07-10 03:04:59 +0000651 Writer.addRecord(std::move(Record11), Err);
Xinliang David Li872df222016-01-08 06:54:27 +0000652 // Merge profile data.
David Blaikie98cce002017-07-10 03:04:59 +0000653 Writer.addRecord(std::move(Record12), Err);
Xinliang David Li872df222016-01-08 06:54:27 +0000654
655 auto Profile = Writer.writeBuffer();
656 readProfile(std::move(Profile));
657
Vedant Kumar9152fd12016-05-19 03:54:45 +0000658 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
David Blaikie94b98b22017-07-07 21:02:59 +0000659 EXPECT_THAT_ERROR(R.takeError(), Succeeded());
Xinliang David Li872df222016-01-08 06:54:27 +0000660 std::unique_ptr<InstrProfValueData[]> VD(
David Blaikiefed557e2016-02-09 01:02:24 +0000661 R->getValueForSite(IPVK_IndirectCallTarget, 0));
662 ASSERT_EQ(2U, R->getNumValueSites(IPVK_IndirectCallTarget));
663 ASSERT_EQ(255U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
NAKAMURA Takumi249edf32016-01-08 07:58:20 +0000664 for (unsigned I = 0; I < 255; I++) {
Xinliang David Li872df222016-01-08 06:54:27 +0000665 ASSERT_EQ(VD[I].Value, 509 - I);
666 ASSERT_EQ(VD[I].Count, 1509 - I);
667 }
668}
669
Xinliang David Li8e6b9172016-05-13 00:23:49 +0000670static void addValueProfData(InstrProfRecord &Record) {
671 Record.reserveSites(IPVK_IndirectCallTarget, 5);
672 InstrProfValueData VD0[] = {{uint64_t(callee1), 400},
673 {uint64_t(callee2), 1000},
674 {uint64_t(callee3), 500},
675 {uint64_t(callee4), 300},
676 {uint64_t(callee5), 100}};
677 Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 5, nullptr);
678 InstrProfValueData VD1[] = {{uint64_t(callee5), 800},
679 {uint64_t(callee3), 1000},
680 {uint64_t(callee2), 2500},
681 {uint64_t(callee1), 1300}};
682 Record.addValueData(IPVK_IndirectCallTarget, 1, VD1, 4, nullptr);
683 InstrProfValueData VD2[] = {{uint64_t(callee6), 800},
684 {uint64_t(callee3), 1000},
685 {uint64_t(callee4), 5500}};
686 Record.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr);
687 InstrProfValueData VD3[] = {{uint64_t(callee2), 1800},
688 {uint64_t(callee3), 2000}};
689 Record.addValueData(IPVK_IndirectCallTarget, 3, VD3, 2, nullptr);
690 Record.addValueData(IPVK_IndirectCallTarget, 4, nullptr, 0, nullptr);
691}
Xinliang David Lied966772015-11-25 23:31:18 +0000692
Xinliang David Li8e6b9172016-05-13 00:23:49 +0000693TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write) {
David Blaikiecf9d52c2017-07-06 19:00:12 +0000694 InstrProfRecord SrcRecord({1ULL << 31, 2});
Xinliang David Li8e6b9172016-05-13 00:23:49 +0000695 addValueProfData(SrcRecord);
696 std::unique_ptr<ValueProfData> VPData =
697 ValueProfData::serializeFrom(SrcRecord);
Xinliang David Lied966772015-11-25 23:31:18 +0000698
David Blaikiecf9d52c2017-07-06 19:00:12 +0000699 InstrProfRecord Record({1ULL << 31, 2});
Eugene Zelenko6ac3f732016-01-26 18:48:36 +0000700 VPData->deserializeTo(Record, nullptr);
Xinliang David Lied966772015-11-25 23:31:18 +0000701
702 // Now read data from Record and sanity check the data
703 ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget));
704 ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
705 ASSERT_EQ(4U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
706 ASSERT_EQ(3U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
707 ASSERT_EQ(2U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
708 ASSERT_EQ(0U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 4));
709
710 auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
711 return VD1.Count > VD2.Count;
712 };
713 std::unique_ptr<InstrProfValueData[]> VD_0(
714 Record.getValueForSite(IPVK_IndirectCallTarget, 0));
715 std::sort(&VD_0[0], &VD_0[5], Cmp);
716 ASSERT_EQ(StringRef((const char *)VD_0[0].Value, 7), StringRef("callee2"));
717 ASSERT_EQ(1000U, VD_0[0].Count);
718 ASSERT_EQ(StringRef((const char *)VD_0[1].Value, 7), StringRef("callee3"));
719 ASSERT_EQ(500U, VD_0[1].Count);
720 ASSERT_EQ(StringRef((const char *)VD_0[2].Value, 7), StringRef("callee1"));
721 ASSERT_EQ(400U, VD_0[2].Count);
722 ASSERT_EQ(StringRef((const char *)VD_0[3].Value, 7), StringRef("callee4"));
723 ASSERT_EQ(300U, VD_0[3].Count);
724 ASSERT_EQ(StringRef((const char *)VD_0[4].Value, 7), StringRef("callee5"));
725 ASSERT_EQ(100U, VD_0[4].Count);
726
727 std::unique_ptr<InstrProfValueData[]> VD_1(
728 Record.getValueForSite(IPVK_IndirectCallTarget, 1));
729 std::sort(&VD_1[0], &VD_1[4], Cmp);
730 ASSERT_EQ(StringRef((const char *)VD_1[0].Value, 7), StringRef("callee2"));
731 ASSERT_EQ(2500U, VD_1[0].Count);
732 ASSERT_EQ(StringRef((const char *)VD_1[1].Value, 7), StringRef("callee1"));
733 ASSERT_EQ(1300U, VD_1[1].Count);
734 ASSERT_EQ(StringRef((const char *)VD_1[2].Value, 7), StringRef("callee3"));
735 ASSERT_EQ(1000U, VD_1[2].Count);
736 ASSERT_EQ(StringRef((const char *)VD_1[3].Value, 7), StringRef("callee5"));
737 ASSERT_EQ(800U, VD_1[3].Count);
738
739 std::unique_ptr<InstrProfValueData[]> VD_2(
740 Record.getValueForSite(IPVK_IndirectCallTarget, 2));
741 std::sort(&VD_2[0], &VD_2[3], Cmp);
742 ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee4"));
743 ASSERT_EQ(5500U, VD_2[0].Count);
744 ASSERT_EQ(StringRef((const char *)VD_2[1].Value, 7), StringRef("callee3"));
745 ASSERT_EQ(1000U, VD_2[1].Count);
746 ASSERT_EQ(StringRef((const char *)VD_2[2].Value, 7), StringRef("callee6"));
747 ASSERT_EQ(800U, VD_2[2].Count);
748
749 std::unique_ptr<InstrProfValueData[]> VD_3(
750 Record.getValueForSite(IPVK_IndirectCallTarget, 3));
751 std::sort(&VD_3[0], &VD_3[2], Cmp);
752 ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee3"));
753 ASSERT_EQ(2000U, VD_3[0].Count);
754 ASSERT_EQ(StringRef((const char *)VD_3[1].Value, 7), StringRef("callee2"));
755 ASSERT_EQ(1800U, VD_3[1].Count);
Xinliang David Lied966772015-11-25 23:31:18 +0000756}
757
Xinliang David Li8e6b9172016-05-13 00:23:49 +0000758TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write_mapping) {
Xinliang David Li28464482016-04-10 03:32:02 +0000759
David Blaikiecf9d52c2017-07-06 19:00:12 +0000760 NamedInstrProfRecord SrcRecord("caller", 0x1234, {1ULL << 31, 2});
Xinliang David Li8e6b9172016-05-13 00:23:49 +0000761 addValueProfData(SrcRecord);
762 std::unique_ptr<ValueProfData> VPData =
763 ValueProfData::serializeFrom(SrcRecord);
Xinliang David Li28464482016-04-10 03:32:02 +0000764
David Blaikiecf9d52c2017-07-06 19:00:12 +0000765 NamedInstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2});
Xinliang David Li28464482016-04-10 03:32:02 +0000766 InstrProfSymtab Symtab;
767 Symtab.mapAddress(uint64_t(callee1), 0x1000ULL);
768 Symtab.mapAddress(uint64_t(callee2), 0x2000ULL);
769 Symtab.mapAddress(uint64_t(callee3), 0x3000ULL);
770 Symtab.mapAddress(uint64_t(callee4), 0x4000ULL);
771 // Missing mapping for callee5
772 Symtab.finalizeSymtab();
773
774 VPData->deserializeTo(Record, &Symtab.getAddrHashMap());
775
776 // Now read data from Record and sanity check the data
Xinliang David Li8e6b9172016-05-13 00:23:49 +0000777 ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget));
Xinliang David Li28464482016-04-10 03:32:02 +0000778 ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
779
780 auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
781 return VD1.Count > VD2.Count;
782 };
783 std::unique_ptr<InstrProfValueData[]> VD_0(
784 Record.getValueForSite(IPVK_IndirectCallTarget, 0));
785 std::sort(&VD_0[0], &VD_0[5], Cmp);
786 ASSERT_EQ(VD_0[0].Value, 0x2000ULL);
787 ASSERT_EQ(1000U, VD_0[0].Count);
788 ASSERT_EQ(VD_0[1].Value, 0x3000ULL);
789 ASSERT_EQ(500U, VD_0[1].Count);
790 ASSERT_EQ(VD_0[2].Value, 0x1000ULL);
791 ASSERT_EQ(400U, VD_0[2].Count);
792
793 // callee5 does not have a mapped value -- default to 0.
794 ASSERT_EQ(VD_0[4].Value, 0ULL);
795}
796
Vedant Kumar00dab222016-01-29 22:54:45 +0000797TEST_P(MaybeSparseInstrProfTest, get_max_function_count) {
David Blaikie98cce002017-07-10 03:04:59 +0000798 Writer.addRecord({"foo", 0x1234, {1ULL << 31, 2}}, Err);
799 Writer.addRecord({"bar", 0, {1ULL << 63}}, Err);
800 Writer.addRecord({"baz", 0x5678, {0, 0, 0, 0}}, Err);
Justin Bogner2b6c5372015-02-18 01:58:17 +0000801 auto Profile = Writer.writeBuffer();
802 readProfile(std::move(Profile));
803
804 ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount());
805}
806
Vedant Kumar00dab222016-01-29 22:54:45 +0000807TEST_P(MaybeSparseInstrProfTest, get_weighted_function_counts) {
David Blaikie98cce002017-07-10 03:04:59 +0000808 Writer.addRecord({"foo", 0x1234, {1, 2}}, 3, Err);
809 Writer.addRecord({"foo", 0x1235, {3, 4}}, 5, Err);
Nathan Slingerland7f5b47d2015-12-15 17:37:09 +0000810 auto Profile = Writer.writeBuffer();
811 readProfile(std::move(Profile));
812
813 std::vector<uint64_t> Counts;
David Blaikie94b98b22017-07-07 21:02:59 +0000814 EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1234, Counts),
815 Succeeded());
Nathan Slingerland7f5b47d2015-12-15 17:37:09 +0000816 ASSERT_EQ(2U, Counts.size());
817 ASSERT_EQ(3U, Counts[0]);
818 ASSERT_EQ(6U, Counts[1]);
819
David Blaikie94b98b22017-07-07 21:02:59 +0000820 EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1235, Counts),
821 Succeeded());
Nathan Slingerland7f5b47d2015-12-15 17:37:09 +0000822 ASSERT_EQ(2U, Counts.size());
823 ASSERT_EQ(15U, Counts[0]);
824 ASSERT_EQ(20U, Counts[1]);
825}
826
Xinliang David Lia0601e72016-02-09 05:47:08 +0000827// Testing symtab creator interface used by indexed profile reader.
Vedant Kumar00dab222016-01-29 22:54:45 +0000828TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_test) {
Xinliang David Li2ee5c4d2015-12-19 07:44:57 +0000829 std::vector<StringRef> FuncNames;
830 FuncNames.push_back("func1");
831 FuncNames.push_back("func2");
832 FuncNames.push_back("func3");
833 FuncNames.push_back("bar1");
834 FuncNames.push_back("bar2");
835 FuncNames.push_back("bar3");
836 InstrProfSymtab Symtab;
David Blaikie94b98b22017-07-07 21:02:59 +0000837 EXPECT_THAT_ERROR(Symtab.create(FuncNames), Succeeded());
Xinliang David Li2ee5c4d2015-12-19 07:44:57 +0000838 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
839 ASSERT_EQ(StringRef("func1"), R);
840 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
841 ASSERT_EQ(StringRef("func2"), R);
842 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
843 ASSERT_EQ(StringRef("func3"), R);
844 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
845 ASSERT_EQ(StringRef("bar1"), R);
846 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
847 ASSERT_EQ(StringRef("bar2"), R);
848 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
849 ASSERT_EQ(StringRef("bar3"), R);
Xinliang David Lic96d3d12015-12-19 18:20:09 +0000850
Xinliang David Li86b4b912016-02-10 06:36:55 +0000851 // negative tests
852 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar4"));
853 ASSERT_EQ(StringRef(), R);
854 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("foo4"));
855 ASSERT_EQ(StringRef(), R);
856
Xinliang David Lic96d3d12015-12-19 18:20:09 +0000857 // Now incrementally update the symtab
David Blaikie94b98b22017-07-07 21:02:59 +0000858 EXPECT_THAT_ERROR(Symtab.addFuncName("blah_1"), Succeeded());
859 EXPECT_THAT_ERROR(Symtab.addFuncName("blah_2"), Succeeded());
860 EXPECT_THAT_ERROR(Symtab.addFuncName("blah_3"), Succeeded());
Xinliang David Lic96d3d12015-12-19 18:20:09 +0000861 // Finalize it
862 Symtab.finalizeSymtab();
863
864 // Check again
865 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_1"));
866 ASSERT_EQ(StringRef("blah_1"), R);
867 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_2"));
868 ASSERT_EQ(StringRef("blah_2"), R);
869 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_3"));
870 ASSERT_EQ(StringRef("blah_3"), R);
871 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
872 ASSERT_EQ(StringRef("func1"), R);
873 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
874 ASSERT_EQ(StringRef("func2"), R);
875 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
876 ASSERT_EQ(StringRef("func3"), R);
877 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
878 ASSERT_EQ(StringRef("bar1"), R);
879 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
880 ASSERT_EQ(StringRef("bar2"), R);
881 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
882 ASSERT_EQ(StringRef("bar3"), R);
Xinliang David Li2ee5c4d2015-12-19 07:44:57 +0000883}
884
Vedant Kumarb5794ca2017-06-20 01:38:56 +0000885// Test that we get an error when creating a bogus symtab.
886TEST_P(MaybeSparseInstrProfTest, instr_prof_bogus_symtab_empty_func_name) {
887 InstrProfSymtab Symtab;
David Blaikie94b98b22017-07-07 21:02:59 +0000888 EXPECT_TRUE(ErrorEquals(instrprof_error::malformed, Symtab.addFuncName("")));
Vedant Kumarb5794ca2017-06-20 01:38:56 +0000889}
890
Xinliang David Lia0601e72016-02-09 05:47:08 +0000891// Testing symtab creator interface used by value profile transformer.
Vedant Kumar00dab222016-01-29 22:54:45 +0000892TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_module_test) {
Xinliang David Li59411db2016-01-20 01:26:34 +0000893 LLVMContext Ctx;
894 std::unique_ptr<Module> M = llvm::make_unique<Module>("MyModule.cpp", Ctx);
895 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
896 /*isVarArg=*/false);
897 Function::Create(FTy, Function::ExternalLinkage, "Gfoo", M.get());
898 Function::Create(FTy, Function::ExternalLinkage, "Gblah", M.get());
899 Function::Create(FTy, Function::ExternalLinkage, "Gbar", M.get());
900 Function::Create(FTy, Function::InternalLinkage, "Ifoo", M.get());
901 Function::Create(FTy, Function::InternalLinkage, "Iblah", M.get());
902 Function::Create(FTy, Function::InternalLinkage, "Ibar", M.get());
903 Function::Create(FTy, Function::PrivateLinkage, "Pfoo", M.get());
904 Function::Create(FTy, Function::PrivateLinkage, "Pblah", M.get());
905 Function::Create(FTy, Function::PrivateLinkage, "Pbar", M.get());
906 Function::Create(FTy, Function::WeakODRLinkage, "Wfoo", M.get());
907 Function::Create(FTy, Function::WeakODRLinkage, "Wblah", M.get());
908 Function::Create(FTy, Function::WeakODRLinkage, "Wbar", M.get());
909
910 InstrProfSymtab ProfSymtab;
David Blaikie94b98b22017-07-07 21:02:59 +0000911 EXPECT_THAT_ERROR(ProfSymtab.create(*M), Succeeded());
Xinliang David Li59411db2016-01-20 01:26:34 +0000912
913 StringRef Funcs[] = {"Gfoo", "Gblah", "Gbar", "Ifoo", "Iblah", "Ibar",
914 "Pfoo", "Pblah", "Pbar", "Wfoo", "Wblah", "Wbar"};
915
916 for (unsigned I = 0; I < sizeof(Funcs) / sizeof(*Funcs); I++) {
917 Function *F = M->getFunction(Funcs[I]);
Eugene Zelenko6ac3f732016-01-26 18:48:36 +0000918 ASSERT_TRUE(F != nullptr);
Xinliang David Lida656fe2016-01-20 02:49:53 +0000919 std::string PGOName = getPGOFuncName(*F);
Xinliang David Li3865fdc2016-01-22 18:13:34 +0000920 uint64_t Key = IndexedInstrProf::ComputeHash(PGOName);
Xinliang David Lida656fe2016-01-20 02:49:53 +0000921 ASSERT_EQ(StringRef(PGOName),
Xinliang David Li3865fdc2016-01-22 18:13:34 +0000922 ProfSymtab.getFuncName(Key));
923 ASSERT_EQ(StringRef(Funcs[I]), ProfSymtab.getOrigFuncName(Key));
Xinliang David Li59411db2016-01-20 01:26:34 +0000924 }
925}
926
Xinliang David Lia0601e72016-02-09 05:47:08 +0000927// Testing symtab serialization and creator/deserialization interface
928// used by coverage map reader, and raw profile reader.
Vedant Kumar00dab222016-01-29 22:54:45 +0000929TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_compression_test) {
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000930 std::vector<std::string> FuncNames1;
931 std::vector<std::string> FuncNames2;
Xinliang David Lic2f25cc42016-02-09 05:36:57 +0000932 for (int I = 0; I < 3; I++) {
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000933 std::string str;
934 raw_string_ostream OS(str);
935 OS << "func_" << I;
936 FuncNames1.push_back(OS.str());
937 str.clear();
Vedant Kumar86705ba2016-03-28 21:06:42 +0000938 OS << "f oooooooooooooo_" << I;
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000939 FuncNames1.push_back(OS.str());
940 str.clear();
941 OS << "BAR_" << I;
942 FuncNames2.push_back(OS.str());
943 str.clear();
944 OS << "BlahblahBlahblahBar_" << I;
945 FuncNames2.push_back(OS.str());
946 }
947
Xinliang David Lidd4ae7b2016-01-29 22:29:15 +0000948 for (bool DoCompression : {false, true}) {
949 // Compressing:
950 std::string FuncNameStrings1;
David Blaikie94b98b22017-07-07 21:02:59 +0000951 EXPECT_THAT_ERROR(collectPGOFuncNameStrings(
952 FuncNames1, (DoCompression && zlib::isAvailable()),
953 FuncNameStrings1),
954 Succeeded());
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000955
Xinliang David Lidd4ae7b2016-01-29 22:29:15 +0000956 // Compressing:
957 std::string FuncNameStrings2;
David Blaikie94b98b22017-07-07 21:02:59 +0000958 EXPECT_THAT_ERROR(collectPGOFuncNameStrings(
959 FuncNames2, (DoCompression && zlib::isAvailable()),
960 FuncNameStrings2),
961 Succeeded());
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000962
Xinliang David Lic2f25cc42016-02-09 05:36:57 +0000963 for (int Padding = 0; Padding < 2; Padding++) {
964 // Join with paddings :
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000965 std::string FuncNameStrings = FuncNameStrings1;
966 for (int P = 0; P < Padding; P++) {
967 FuncNameStrings.push_back('\0');
968 }
969 FuncNameStrings += FuncNameStrings2;
970
Xinliang David Li8dec8b12016-01-04 23:59:14 +0000971 // Now decompress:
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000972 InstrProfSymtab Symtab;
David Blaikie94b98b22017-07-07 21:02:59 +0000973 EXPECT_THAT_ERROR(Symtab.create(StringRef(FuncNameStrings)), Succeeded());
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000974
Xinliang David Li8dec8b12016-01-04 23:59:14 +0000975 // Now do the checks:
976 // First sampling some data points:
Xinliang David Lia8ba7af2016-01-29 21:26:31 +0000977 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[0]));
Xinliang David Li8dec8b12016-01-04 23:59:14 +0000978 ASSERT_EQ(StringRef("func_0"), R);
979 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[1]));
Vedant Kumar86705ba2016-03-28 21:06:42 +0000980 ASSERT_EQ(StringRef("f oooooooooooooo_0"), R);
Xinliang David Lic2f25cc42016-02-09 05:36:57 +0000981 for (int I = 0; I < 3; I++) {
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000982 std::string N[4];
983 N[0] = FuncNames1[2 * I];
984 N[1] = FuncNames1[2 * I + 1];
985 N[2] = FuncNames2[2 * I];
986 N[3] = FuncNames2[2 * I + 1];
987 for (int J = 0; J < 4; J++) {
988 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(N[J]));
989 ASSERT_EQ(StringRef(N[J]), R);
990 }
991 }
992 }
993 }
994}
995
Vedant Kumar00dab222016-01-29 22:54:45 +0000996TEST_F(SparseInstrProfTest, preserve_no_records) {
David Blaikie98cce002017-07-10 03:04:59 +0000997 Writer.addRecord({"foo", 0x1234, {0}}, Err);
998 Writer.addRecord({"bar", 0x4321, {0, 0}}, Err);
Vedant Kumar910d3d02017-07-10 21:44:43 +0000999 Writer.addRecord({"baz", 0x4321, {0, 0, 0}}, Err);
Vedant Kumar00dab222016-01-29 22:54:45 +00001000
Vedant Kumar00dab222016-01-29 22:54:45 +00001001 auto Profile = Writer.writeBuffer();
1002 readProfile(std::move(Profile));
1003
1004 auto I = Reader->begin(), E = Reader->end();
1005 ASSERT_TRUE(I == E);
1006}
1007
1008INSTANTIATE_TEST_CASE_P(MaybeSparse, MaybeSparseInstrProfTest,
Galina Kistanova94177352017-06-04 05:30:26 +00001009 ::testing::Bool(),);
Vedant Kumar00dab222016-01-29 22:54:45 +00001010
Justin Bogner2b6c5372015-02-18 01:58:17 +00001011} // end anonymous namespace