1 //===- unittest/ProfileData/InstrProfTest.cpp -------------------*- C++ -*-===//
2 //
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 
10 #include "llvm/IR/Function.h"
11 #include "llvm/IR/IRBuilder.h"
12 #include "llvm/IR/LLVMContext.h"
13 #include "llvm/IR/Module.h"
14 #include "llvm/ProfileData/InstrProfReader.h"
15 #include "llvm/ProfileData/InstrProfWriter.h"
16 #include "llvm/Support/Compression.h"
17 #include "llvm/Testing/Support/Error.h"
18 #include "llvm/Testing/Support/SupportHelpers.h"
19 #include "gtest/gtest.h"
20 #include <cstdarg>
21 
22 using namespace llvm;
23 
24 LLVM_NODISCARD static ::testing::AssertionResult
25 ErrorEquals(instrprof_error Expected, Error E) {
26   instrprof_error Found;
27   std::string FoundMsg;
28   handleAllErrors(std::move(E), [&](const InstrProfError &IPE) {
29     Found = IPE.get();
30     FoundMsg = IPE.message();
31   });
32   if (Expected == Found)
33     return ::testing::AssertionSuccess();
34   return ::testing::AssertionFailure() << "error: " << FoundMsg << "\n";
35 }
36 
37 namespace {
38 
39 struct InstrProfTest : ::testing::Test {
40   InstrProfWriter Writer;
41   std::unique_ptr<IndexedInstrProfReader> Reader;
42 
43   void SetUp() { Writer.setOutputSparse(false); }
44 
45   void readProfile(std::unique_ptr<MemoryBuffer> Profile) {
46     auto ReaderOrErr = IndexedInstrProfReader::create(std::move(Profile));
47     EXPECT_THAT_ERROR(ReaderOrErr.takeError(), Succeeded());
48     Reader = std::move(ReaderOrErr.get());
49   }
50 };
51 
52 struct SparseInstrProfTest : public InstrProfTest {
53   void SetUp() { Writer.setOutputSparse(true); }
54 };
55 
56 struct MaybeSparseInstrProfTest : public InstrProfTest,
57                                   public ::testing::WithParamInterface<bool> {
58   void SetUp() { Writer.setOutputSparse(GetParam()); }
59 };
60 
61 TEST_P(MaybeSparseInstrProfTest, write_and_read_empty_profile) {
62   auto Profile = Writer.writeBuffer();
63   readProfile(std::move(Profile));
64   ASSERT_TRUE(Reader->begin() == Reader->end());
65 }
66 
67 static const auto Err = [](Error E) {
68   consumeError(std::move(E));
69   FAIL();
70 };
71 
72 TEST_P(MaybeSparseInstrProfTest, write_and_read_one_function) {
73   Writer.addRecord({"foo", 0x1234, {1, 2, 3, 4}}, Err);
74   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 
89 TEST_P(MaybeSparseInstrProfTest, get_instr_prof_record) {
90   Writer.addRecord({"foo", 0x1234, {1, 2}}, Err);
91   Writer.addRecord({"foo", 0x1235, {3, 4}}, Err);
92   auto Profile = Writer.writeBuffer();
93   readProfile(std::move(Profile));
94 
95   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("foo", 0x1234);
96   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
97   ASSERT_EQ(2U, R->Counts.size());
98   ASSERT_EQ(1U, R->Counts[0]);
99   ASSERT_EQ(2U, R->Counts[1]);
100 
101   R = Reader->getInstrProfRecord("foo", 0x1235);
102   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
103   ASSERT_EQ(2U, R->Counts.size());
104   ASSERT_EQ(3U, R->Counts[0]);
105   ASSERT_EQ(4U, R->Counts[1]);
106 
107   R = Reader->getInstrProfRecord("foo", 0x5678);
108   ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, R.takeError()));
109 
110   R = Reader->getInstrProfRecord("bar", 0x1234);
111   ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, R.takeError()));
112 }
113 
114 TEST_P(MaybeSparseInstrProfTest, get_function_counts) {
115   Writer.addRecord({"foo", 0x1234, {1, 2}}, Err);
116   Writer.addRecord({"foo", 0x1235, {3, 4}}, Err);
117   auto Profile = Writer.writeBuffer();
118   readProfile(std::move(Profile));
119 
120   std::vector<uint64_t> Counts;
121   EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1234, Counts),
122                     Succeeded());
123   ASSERT_EQ(2U, Counts.size());
124   ASSERT_EQ(1U, Counts[0]);
125   ASSERT_EQ(2U, Counts[1]);
126 
127   EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1235, Counts),
128                     Succeeded());
129   ASSERT_EQ(2U, Counts.size());
130   ASSERT_EQ(3U, Counts[0]);
131   ASSERT_EQ(4U, Counts[1]);
132 
133   Error E1 = Reader->getFunctionCounts("foo", 0x5678, Counts);
134   ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, std::move(E1)));
135 
136   Error E2 = Reader->getFunctionCounts("bar", 0x1234, Counts);
137   ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, std::move(E2)));
138 }
139 
140 // Profile data is copied from general.proftext
141 TEST_F(InstrProfTest, get_profile_summary) {
142   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);
151   auto Profile = Writer.writeBuffer();
152   readProfile(std::move(Profile));
153 
154   auto VerifySummary = [](ProfileSummary &IPS) mutable {
155     ASSERT_EQ(ProfileSummary::PSK_Instr, IPS.getKind());
156     ASSERT_EQ(2305843009213693952U, IPS.getMaxFunctionCount());
157     ASSERT_EQ(2305843009213693952U, IPS.getMaxCount());
158     ASSERT_EQ(10U, IPS.getNumCounts());
159     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     };
165     auto EightyPerc = find_if(Details, Predicate);
166     Cutoff = 900000;
167     auto NinetyPerc = find_if(Details, Predicate);
168     Cutoff = 950000;
169     auto NinetyFivePerc = find_if(Details, Predicate);
170     Cutoff = 990000;
171     auto NinetyNinePerc = find_if(Details, Predicate);
172     ASSERT_EQ(576460752303423488U, EightyPerc->MinCount);
173     ASSERT_EQ(288230376151711744U, NinetyPerc->MinCount);
174     ASSERT_EQ(288230376151711744U, NinetyFivePerc->MinCount);
175     ASSERT_EQ(72057594037927936U, NinetyNinePerc->MinCount);
176   };
177   ProfileSummary &PS = Reader->getSummary();
178   VerifySummary(PS);
179 
180   // Test that conversion of summary to and from Metadata works.
181   LLVMContext Context;
182   Metadata *MD = PS.getMD(Context);
183   ASSERT_TRUE(MD);
184   ProfileSummary *PSFromMD = ProfileSummary::getFromMD(MD);
185   ASSERT_TRUE(PSFromMD);
186   VerifySummary(*PSFromMD);
187   delete PSFromMD;
188 
189   // Test that summary can be attached to and read back from module.
190   Module M("my_module", Context);
191   M.setProfileSummary(MD);
192   MD = M.getProfileSummary();
193   ASSERT_TRUE(MD);
194   PSFromMD = ProfileSummary::getFromMD(MD);
195   ASSERT_TRUE(PSFromMD);
196   VerifySummary(*PSFromMD);
197   delete PSFromMD;
198 }
199 
200 TEST_F(InstrProfTest, test_writer_merge) {
201   Writer.addRecord({"func1", 0x1234, {42}}, Err);
202 
203   InstrProfWriter Writer2;
204   Writer2.addRecord({"func2", 0x1234, {0, 0}}, Err);
205 
206   Writer.mergeRecordsFromWriter(std::move(Writer2), Err);
207 
208   auto Profile = Writer.writeBuffer();
209   readProfile(std::move(Profile));
210 
211   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("func1", 0x1234);
212   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
213   ASSERT_EQ(1U, R->Counts.size());
214   ASSERT_EQ(42U, R->Counts[0]);
215 
216   R = Reader->getInstrProfRecord("func2", 0x1234);
217   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
218   ASSERT_EQ(2U, R->Counts.size());
219   ASSERT_EQ(0U, R->Counts[0]);
220   ASSERT_EQ(0U, R->Counts[1]);
221 }
222 
223 static const char callee1[] = "callee1";
224 static const char callee2[] = "callee2";
225 static const char callee3[] = "callee3";
226 static const char callee4[] = "callee4";
227 static const char callee5[] = "callee5";
228 static const char callee6[] = "callee6";
229 
230 TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write) {
231   NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
232 
233   // 4 value sites.
234   Record1.reserveSites(IPVK_IndirectCallTarget, 4);
235   InstrProfValueData VD0[] = {
236       {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
237   Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
238   // No value profile data at the second site.
239   Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
240   InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
241   Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
242   InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
243   Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
244 
245   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);
249   auto Profile = Writer.writeBuffer();
250   readProfile(std::move(Profile));
251 
252   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
253   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
254   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));
259 
260   uint64_t TotalC;
261   std::unique_ptr<InstrProfValueData[]> VD =
262       R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC);
263 
264   ASSERT_EQ(3U, VD[0].Count);
265   ASSERT_EQ(2U, VD[1].Count);
266   ASSERT_EQ(1U, VD[2].Count);
267   ASSERT_EQ(6U, TotalC);
268 
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 
274 TEST_P(MaybeSparseInstrProfTest, annotate_vp_data) {
275   NamedInstrProfRecord Record("caller", 0x1234, {1, 2});
276   Record.reserveSites(IPVK_IndirectCallTarget, 1);
277   InstrProfValueData VD0[] = {{1000, 1}, {2000, 2}, {3000, 3}, {5000, 5},
278                               {4000, 4}, {6000, 6}};
279   Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 6, nullptr);
280   Writer.addRecord(std::move(Record), Err);
281   auto Profile = Writer.writeBuffer();
282   readProfile(std::move(Profile));
283   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
284   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
285 
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);
301   annotateValueSite(*M, *Inst, R.get(), IPVK_IndirectCallTarget, 0);
302 
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);
310   ASSERT_EQ(21U, T);
311   // The result should be sorted already:
312   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);
318   Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 1, ValueData,
319                                  N, T);
320   ASSERT_TRUE(Res);
321   ASSERT_EQ(1U, N);
322   ASSERT_EQ(21U, T);
323 
324   Res = getValueProfDataFromInst(*Inst2, IPVK_IndirectCallTarget, 5, ValueData,
325                                  N, T);
326   ASSERT_FALSE(Res);
327 
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);
347 
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}};
353   annotateValueSite(*M, *Inst, makeArrayRef(VD0Sorted).slice(2), 10,
354                     IPVK_IndirectCallTarget, 5);
355   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);
368 }
369 
370 TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_with_weight) {
371   NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
372 
373   // 4 value sites.
374   Record1.reserveSites(IPVK_IndirectCallTarget, 4);
375   InstrProfValueData VD0[] = {
376       {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
377   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);
380   InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
381   Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
382   InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
383   Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
384 
385   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);
389   auto Profile = Writer.writeBuffer();
390   readProfile(std::move(Profile));
391 
392   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
393   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
394   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));
399 
400   uint64_t TotalC;
401   std::unique_ptr<InstrProfValueData[]> VD =
402       R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC);
403   ASSERT_EQ(30U, VD[0].Count);
404   ASSERT_EQ(20U, VD[1].Count);
405   ASSERT_EQ(10U, VD[2].Count);
406   ASSERT_EQ(60U, TotalC);
407 
408   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 
413 TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_big_endian) {
414   NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
415 
416   // 4 value sites.
417   Record1.reserveSites(IPVK_IndirectCallTarget, 4);
418   InstrProfValueData VD0[] = {
419       {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
420   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);
423   InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
424   Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
425   InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
426   Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
427 
428   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);
432 
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 
442   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
443   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
444   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));
449 
450   std::unique_ptr<InstrProfValueData[]> VD =
451       R->getValueForSite(IPVK_IndirectCallTarget, 0);
452   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 
460 TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge1) {
461   static const char caller[] = "caller";
462   NamedInstrProfRecord Record11(caller, 0x1234, {1, 2});
463   NamedInstrProfRecord Record12(caller, 0x1234, {1, 2});
464 
465   // 5 value sites.
466   Record11.reserveSites(IPVK_IndirectCallTarget, 5);
467   InstrProfValueData VD0[] = {{uint64_t(callee1), 1},
468                               {uint64_t(callee2), 2},
469                               {uint64_t(callee3), 3},
470                               {uint64_t(callee4), 4}};
471   Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 4, nullptr);
472 
473   // No value profile data at the second site.
474   Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
475 
476   InstrProfValueData VD2[] = {
477       {uint64_t(callee1), 1}, {uint64_t(callee2), 2}, {uint64_t(callee3), 3}};
478   Record11.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr);
479 
480   InstrProfValueData VD3[] = {{uint64_t(callee1), 1}};
481   Record11.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
482 
483   InstrProfValueData VD4[] = {{uint64_t(callee1), 1},
484                               {uint64_t(callee2), 2},
485                               {uint64_t(callee3), 3}};
486   Record11.addValueData(IPVK_IndirectCallTarget, 4, VD4, 3, nullptr);
487 
488   // A different record for the same caller.
489   Record12.reserveSites(IPVK_IndirectCallTarget, 5);
490   InstrProfValueData VD02[] = {{uint64_t(callee2), 5}, {uint64_t(callee3), 3}};
491   Record12.addValueData(IPVK_IndirectCallTarget, 0, VD02, 2, nullptr);
492 
493   // No value profile data at the second site.
494   Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
495 
496   InstrProfValueData VD22[] = {
497       {uint64_t(callee2), 1}, {uint64_t(callee3), 3}, {uint64_t(callee4), 4}};
498   Record12.addValueData(IPVK_IndirectCallTarget, 2, VD22, 3, nullptr);
499 
500   Record12.addValueData(IPVK_IndirectCallTarget, 3, nullptr, 0, nullptr);
501 
502   InstrProfValueData VD42[] = {{uint64_t(callee1), 1},
503                                {uint64_t(callee2), 2},
504                                {uint64_t(callee3), 3}};
505   Record12.addValueData(IPVK_IndirectCallTarget, 4, VD42, 3, nullptr);
506 
507   Writer.addRecord(std::move(Record11), Err);
508   // Merge profile data.
509   Writer.addRecord(std::move(Record12), Err);
510 
511   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);
516   auto Profile = Writer.writeBuffer();
517   readProfile(std::move(Profile));
518 
519   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
520   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
521   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));
527 
528   std::unique_ptr<InstrProfValueData[]> VD =
529       R->getValueForSite(IPVK_IndirectCallTarget, 0);
530   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(
540       R->getValueForSite(IPVK_IndirectCallTarget, 2));
541   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(
551       R->getValueForSite(IPVK_IndirectCallTarget, 3));
552   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(
556       R->getValueForSite(IPVK_IndirectCallTarget, 4));
557   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 
565 TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge1_saturation) {
566   static const char bar[] = "bar";
567 
568   const uint64_t Max = std::numeric_limits<uint64_t>::max();
569 
570   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);
575 
576   // Verify counter overflow.
577   Result = instrprof_error::success;
578   Writer.addRecord({"foo", 0x1234, {Max}}, Err);
579   ASSERT_EQ(Result, instrprof_error::counter_overflow);
580 
581   Result = instrprof_error::success;
582   Writer.addRecord({bar, 0x9012, {8}}, Err);
583   ASSERT_EQ(Result, instrprof_error::success);
584 
585   NamedInstrProfRecord Record4("baz", 0x5678, {3, 4});
586   Record4.reserveSites(IPVK_IndirectCallTarget, 1);
587   InstrProfValueData VD4[] = {{uint64_t(bar), 1}};
588   Record4.addValueData(IPVK_IndirectCallTarget, 0, VD4, 1, nullptr);
589   Result = instrprof_error::success;
590   Writer.addRecord(std::move(Record4), Err);
591   ASSERT_EQ(Result, instrprof_error::success);
592 
593   // Verify value data counter overflow.
594   NamedInstrProfRecord Record5("baz", 0x5678, {5, 6});
595   Record5.reserveSites(IPVK_IndirectCallTarget, 1);
596   InstrProfValueData VD5[] = {{uint64_t(bar), Max}};
597   Record5.addValueData(IPVK_IndirectCallTarget, 0, VD5, 1, nullptr);
598   Result = instrprof_error::success;
599   Writer.addRecord(std::move(Record5), Err);
600   ASSERT_EQ(Result, instrprof_error::counter_overflow);
601 
602   auto Profile = Writer.writeBuffer();
603   readProfile(std::move(Profile));
604 
605   // Verify saturation of counts.
606   Expected<InstrProfRecord> ReadRecord1 =
607       Reader->getInstrProfRecord("foo", 0x1234);
608   EXPECT_THAT_ERROR(ReadRecord1.takeError(), Succeeded());
609   ASSERT_EQ(Max, ReadRecord1->Counts[0]);
610 
611   Expected<InstrProfRecord> ReadRecord2 =
612       Reader->getInstrProfRecord("baz", 0x5678);
613   ASSERT_TRUE(bool(ReadRecord2));
614   ASSERT_EQ(1U, ReadRecord2->getNumValueSites(IPVK_IndirectCallTarget));
615   std::unique_ptr<InstrProfValueData[]> VD =
616       ReadRecord2->getValueForSite(IPVK_IndirectCallTarget, 0);
617   ASSERT_EQ(StringRef("bar"), StringRef((const char *)VD[0].Value, 3));
618   ASSERT_EQ(Max, VD[0].Count);
619 }
620 
621 // This test tests that when there are too many values
622 // for a given site, the merged results are properly
623 // truncated.
624 TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge_site_trunc) {
625   static const char caller[] = "caller";
626 
627   NamedInstrProfRecord Record11(caller, 0x1234, {1, 2});
628   NamedInstrProfRecord Record12(caller, 0x1234, {1, 2});
629 
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 
651   Writer.addRecord(std::move(Record11), Err);
652   // Merge profile data.
653   Writer.addRecord(std::move(Record12), Err);
654 
655   auto Profile = Writer.writeBuffer();
656   readProfile(std::move(Profile));
657 
658   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
659   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
660   std::unique_ptr<InstrProfValueData[]> VD(
661       R->getValueForSite(IPVK_IndirectCallTarget, 0));
662   ASSERT_EQ(2U, R->getNumValueSites(IPVK_IndirectCallTarget));
663   ASSERT_EQ(255U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
664   for (unsigned I = 0; I < 255; I++) {
665     ASSERT_EQ(VD[I].Value, 509 - I);
666     ASSERT_EQ(VD[I].Count, 1509 - I);
667   }
668 }
669 
670 static 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 }
692 
693 TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write) {
694   InstrProfRecord SrcRecord({1ULL << 31, 2});
695   addValueProfData(SrcRecord);
696   std::unique_ptr<ValueProfData> VPData =
697       ValueProfData::serializeFrom(SrcRecord);
698 
699   InstrProfRecord Record({1ULL << 31, 2});
700   VPData->deserializeTo(Record, nullptr);
701 
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   llvm::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   llvm::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   llvm::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   llvm::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);
756 }
757 
758 TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write_mapping) {
759 
760   NamedInstrProfRecord SrcRecord("caller", 0x1234, {1ULL << 31, 2});
761   addValueProfData(SrcRecord);
762   std::unique_ptr<ValueProfData> VPData =
763       ValueProfData::serializeFrom(SrcRecord);
764 
765   NamedInstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2});
766   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 
773   VPData->deserializeTo(Record, &Symtab);
774 
775   // Now read data from Record and sanity check the data
776   ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget));
777   ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
778 
779   auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
780     return VD1.Count > VD2.Count;
781   };
782   std::unique_ptr<InstrProfValueData[]> VD_0(
783       Record.getValueForSite(IPVK_IndirectCallTarget, 0));
784   llvm::sort(&VD_0[0], &VD_0[5], Cmp);
785   ASSERT_EQ(VD_0[0].Value, 0x2000ULL);
786   ASSERT_EQ(1000U, VD_0[0].Count);
787   ASSERT_EQ(VD_0[1].Value, 0x3000ULL);
788   ASSERT_EQ(500U, VD_0[1].Count);
789   ASSERT_EQ(VD_0[2].Value, 0x1000ULL);
790   ASSERT_EQ(400U, VD_0[2].Count);
791 
792   // callee5 does not have a mapped value -- default to 0.
793   ASSERT_EQ(VD_0[4].Value, 0ULL);
794 }
795 
796 TEST_P(MaybeSparseInstrProfTest, get_max_function_count) {
797   Writer.addRecord({"foo", 0x1234, {1ULL << 31, 2}}, Err);
798   Writer.addRecord({"bar", 0, {1ULL << 63}}, Err);
799   Writer.addRecord({"baz", 0x5678, {0, 0, 0, 0}}, Err);
800   auto Profile = Writer.writeBuffer();
801   readProfile(std::move(Profile));
802 
803   ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount());
804 }
805 
806 TEST_P(MaybeSparseInstrProfTest, get_weighted_function_counts) {
807   Writer.addRecord({"foo", 0x1234, {1, 2}}, 3, Err);
808   Writer.addRecord({"foo", 0x1235, {3, 4}}, 5, Err);
809   auto Profile = Writer.writeBuffer();
810   readProfile(std::move(Profile));
811 
812   std::vector<uint64_t> Counts;
813   EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1234, Counts),
814                     Succeeded());
815   ASSERT_EQ(2U, Counts.size());
816   ASSERT_EQ(3U, Counts[0]);
817   ASSERT_EQ(6U, Counts[1]);
818 
819   EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1235, Counts),
820                     Succeeded());
821   ASSERT_EQ(2U, Counts.size());
822   ASSERT_EQ(15U, Counts[0]);
823   ASSERT_EQ(20U, Counts[1]);
824 }
825 
826 // Testing symtab creator interface used by indexed profile reader.
827 TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_test) {
828   std::vector<StringRef> FuncNames;
829   FuncNames.push_back("func1");
830   FuncNames.push_back("func2");
831   FuncNames.push_back("func3");
832   FuncNames.push_back("bar1");
833   FuncNames.push_back("bar2");
834   FuncNames.push_back("bar3");
835   InstrProfSymtab Symtab;
836   EXPECT_THAT_ERROR(Symtab.create(FuncNames), Succeeded());
837   StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
838   ASSERT_EQ(StringRef("func1"), R);
839   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
840   ASSERT_EQ(StringRef("func2"), R);
841   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
842   ASSERT_EQ(StringRef("func3"), R);
843   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
844   ASSERT_EQ(StringRef("bar1"), R);
845   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
846   ASSERT_EQ(StringRef("bar2"), R);
847   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
848   ASSERT_EQ(StringRef("bar3"), R);
849 
850   // negative tests
851   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar4"));
852   ASSERT_EQ(StringRef(), R);
853   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("foo4"));
854   ASSERT_EQ(StringRef(), R);
855 
856   // Now incrementally update the symtab
857   EXPECT_THAT_ERROR(Symtab.addFuncName("blah_1"), Succeeded());
858   EXPECT_THAT_ERROR(Symtab.addFuncName("blah_2"), Succeeded());
859   EXPECT_THAT_ERROR(Symtab.addFuncName("blah_3"), Succeeded());
860 
861   // Check again
862   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_1"));
863   ASSERT_EQ(StringRef("blah_1"), R);
864   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_2"));
865   ASSERT_EQ(StringRef("blah_2"), R);
866   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_3"));
867   ASSERT_EQ(StringRef("blah_3"), R);
868   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
869   ASSERT_EQ(StringRef("func1"), R);
870   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
871   ASSERT_EQ(StringRef("func2"), R);
872   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
873   ASSERT_EQ(StringRef("func3"), R);
874   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
875   ASSERT_EQ(StringRef("bar1"), R);
876   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
877   ASSERT_EQ(StringRef("bar2"), R);
878   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
879   ASSERT_EQ(StringRef("bar3"), R);
880 }
881 
882 // Test that we get an error when creating a bogus symtab.
883 TEST_P(MaybeSparseInstrProfTest, instr_prof_bogus_symtab_empty_func_name) {
884   InstrProfSymtab Symtab;
885   EXPECT_TRUE(ErrorEquals(instrprof_error::malformed, Symtab.addFuncName("")));
886 }
887 
888 // Testing symtab creator interface used by value profile transformer.
889 TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_module_test) {
890   LLVMContext Ctx;
891   std::unique_ptr<Module> M = llvm::make_unique<Module>("MyModule.cpp", Ctx);
892   FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
893                                         /*isVarArg=*/false);
894   Function::Create(FTy, Function::ExternalLinkage, "Gfoo", M.get());
895   Function::Create(FTy, Function::ExternalLinkage, "Gblah", M.get());
896   Function::Create(FTy, Function::ExternalLinkage, "Gbar", M.get());
897   Function::Create(FTy, Function::InternalLinkage, "Ifoo", M.get());
898   Function::Create(FTy, Function::InternalLinkage, "Iblah", M.get());
899   Function::Create(FTy, Function::InternalLinkage, "Ibar", M.get());
900   Function::Create(FTy, Function::PrivateLinkage, "Pfoo", M.get());
901   Function::Create(FTy, Function::PrivateLinkage, "Pblah", M.get());
902   Function::Create(FTy, Function::PrivateLinkage, "Pbar", M.get());
903   Function::Create(FTy, Function::WeakODRLinkage, "Wfoo", M.get());
904   Function::Create(FTy, Function::WeakODRLinkage, "Wblah", M.get());
905   Function::Create(FTy, Function::WeakODRLinkage, "Wbar", M.get());
906 
907   InstrProfSymtab ProfSymtab;
908   EXPECT_THAT_ERROR(ProfSymtab.create(*M), Succeeded());
909 
910   StringRef Funcs[] = {"Gfoo", "Gblah", "Gbar", "Ifoo", "Iblah", "Ibar",
911                        "Pfoo", "Pblah", "Pbar", "Wfoo", "Wblah", "Wbar"};
912 
913   for (unsigned I = 0; I < sizeof(Funcs) / sizeof(*Funcs); I++) {
914     Function *F = M->getFunction(Funcs[I]);
915     ASSERT_TRUE(F != nullptr);
916     std::string PGOName = getPGOFuncName(*F);
917     uint64_t Key = IndexedInstrProf::ComputeHash(PGOName);
918     ASSERT_EQ(StringRef(PGOName),
919               ProfSymtab.getFuncName(Key));
920     ASSERT_EQ(StringRef(Funcs[I]), ProfSymtab.getOrigFuncName(Key));
921   }
922 }
923 
924 // Testing symtab serialization and creator/deserialization interface
925 // used by coverage map reader, and raw profile reader.
926 TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_compression_test) {
927   std::vector<std::string> FuncNames1;
928   std::vector<std::string> FuncNames2;
929   for (int I = 0; I < 3; I++) {
930     std::string str;
931     raw_string_ostream OS(str);
932     OS << "func_" << I;
933     FuncNames1.push_back(OS.str());
934     str.clear();
935     OS << "f oooooooooooooo_" << I;
936     FuncNames1.push_back(OS.str());
937     str.clear();
938     OS << "BAR_" << I;
939     FuncNames2.push_back(OS.str());
940     str.clear();
941     OS << "BlahblahBlahblahBar_" << I;
942     FuncNames2.push_back(OS.str());
943   }
944 
945   for (bool DoCompression : {false, true}) {
946     // Compressing:
947     std::string FuncNameStrings1;
948     EXPECT_THAT_ERROR(collectPGOFuncNameStrings(
949                           FuncNames1, (DoCompression && zlib::isAvailable()),
950                           FuncNameStrings1),
951                       Succeeded());
952 
953     // Compressing:
954     std::string FuncNameStrings2;
955     EXPECT_THAT_ERROR(collectPGOFuncNameStrings(
956                           FuncNames2, (DoCompression && zlib::isAvailable()),
957                           FuncNameStrings2),
958                       Succeeded());
959 
960     for (int Padding = 0; Padding < 2; Padding++) {
961       // Join with paddings :
962       std::string FuncNameStrings = FuncNameStrings1;
963       for (int P = 0; P < Padding; P++) {
964         FuncNameStrings.push_back('\0');
965       }
966       FuncNameStrings += FuncNameStrings2;
967 
968       // Now decompress:
969       InstrProfSymtab Symtab;
970       EXPECT_THAT_ERROR(Symtab.create(StringRef(FuncNameStrings)), Succeeded());
971 
972       // Now do the checks:
973       // First sampling some data points:
974       StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[0]));
975       ASSERT_EQ(StringRef("func_0"), R);
976       R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[1]));
977       ASSERT_EQ(StringRef("f oooooooooooooo_0"), R);
978       for (int I = 0; I < 3; I++) {
979         std::string N[4];
980         N[0] = FuncNames1[2 * I];
981         N[1] = FuncNames1[2 * I + 1];
982         N[2] = FuncNames2[2 * I];
983         N[3] = FuncNames2[2 * I + 1];
984         for (int J = 0; J < 4; J++) {
985           StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(N[J]));
986           ASSERT_EQ(StringRef(N[J]), R);
987         }
988       }
989     }
990   }
991 }
992 
993 TEST_F(SparseInstrProfTest, preserve_no_records) {
994   Writer.addRecord({"foo", 0x1234, {0}}, Err);
995   Writer.addRecord({"bar", 0x4321, {0, 0}}, Err);
996   Writer.addRecord({"baz", 0x4321, {0, 0, 0}}, Err);
997 
998   auto Profile = Writer.writeBuffer();
999   readProfile(std::move(Profile));
1000 
1001   auto I = Reader->begin(), E = Reader->end();
1002   ASSERT_TRUE(I == E);
1003 }
1004 
1005 INSTANTIATE_TEST_CASE_P(MaybeSparse, MaybeSparseInstrProfTest,
1006                         ::testing::Bool(),);
1007 
1008 } // end anonymous namespace
1009