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                    std::unique_ptr<MemoryBuffer> Remapping = nullptr) {
47     auto ReaderOrErr = IndexedInstrProfReader::create(std::move(Profile),
48                                                       std::move(Remapping));
49     EXPECT_THAT_ERROR(ReaderOrErr.takeError(), Succeeded());
50     Reader = std::move(ReaderOrErr.get());
51   }
52 };
53 
54 struct SparseInstrProfTest : public InstrProfTest {
55   void SetUp() { Writer.setOutputSparse(true); }
56 };
57 
58 struct MaybeSparseInstrProfTest : public InstrProfTest,
59                                   public ::testing::WithParamInterface<bool> {
60   void SetUp() { Writer.setOutputSparse(GetParam()); }
61 };
62 
63 TEST_P(MaybeSparseInstrProfTest, write_and_read_empty_profile) {
64   auto Profile = Writer.writeBuffer();
65   readProfile(std::move(Profile));
66   ASSERT_TRUE(Reader->begin() == Reader->end());
67 }
68 
69 static const auto Err = [](Error E) {
70   consumeError(std::move(E));
71   FAIL();
72 };
73 
74 TEST_P(MaybeSparseInstrProfTest, write_and_read_one_function) {
75   Writer.addRecord({"foo", 0x1234, {1, 2, 3, 4}}, Err);
76   auto Profile = Writer.writeBuffer();
77   readProfile(std::move(Profile));
78 
79   auto I = Reader->begin(), E = Reader->end();
80   ASSERT_TRUE(I != E);
81   ASSERT_EQ(StringRef("foo"), I->Name);
82   ASSERT_EQ(0x1234U, I->Hash);
83   ASSERT_EQ(4U, I->Counts.size());
84   ASSERT_EQ(1U, I->Counts[0]);
85   ASSERT_EQ(2U, I->Counts[1]);
86   ASSERT_EQ(3U, I->Counts[2]);
87   ASSERT_EQ(4U, I->Counts[3]);
88   ASSERT_TRUE(++I == E);
89 }
90 
91 TEST_P(MaybeSparseInstrProfTest, get_instr_prof_record) {
92   Writer.addRecord({"foo", 0x1234, {1, 2}}, Err);
93   Writer.addRecord({"foo", 0x1235, {3, 4}}, Err);
94   auto Profile = Writer.writeBuffer();
95   readProfile(std::move(Profile));
96 
97   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("foo", 0x1234);
98   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
99   ASSERT_EQ(2U, R->Counts.size());
100   ASSERT_EQ(1U, R->Counts[0]);
101   ASSERT_EQ(2U, R->Counts[1]);
102 
103   R = Reader->getInstrProfRecord("foo", 0x1235);
104   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
105   ASSERT_EQ(2U, R->Counts.size());
106   ASSERT_EQ(3U, R->Counts[0]);
107   ASSERT_EQ(4U, R->Counts[1]);
108 
109   R = Reader->getInstrProfRecord("foo", 0x5678);
110   ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, R.takeError()));
111 
112   R = Reader->getInstrProfRecord("bar", 0x1234);
113   ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, R.takeError()));
114 }
115 
116 TEST_P(MaybeSparseInstrProfTest, get_function_counts) {
117   Writer.addRecord({"foo", 0x1234, {1, 2}}, Err);
118   Writer.addRecord({"foo", 0x1235, {3, 4}}, Err);
119   auto Profile = Writer.writeBuffer();
120   readProfile(std::move(Profile));
121 
122   std::vector<uint64_t> Counts;
123   EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1234, Counts),
124                     Succeeded());
125   ASSERT_EQ(2U, Counts.size());
126   ASSERT_EQ(1U, Counts[0]);
127   ASSERT_EQ(2U, Counts[1]);
128 
129   EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1235, Counts),
130                     Succeeded());
131   ASSERT_EQ(2U, Counts.size());
132   ASSERT_EQ(3U, Counts[0]);
133   ASSERT_EQ(4U, Counts[1]);
134 
135   Error E1 = Reader->getFunctionCounts("foo", 0x5678, Counts);
136   ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, std::move(E1)));
137 
138   Error E2 = Reader->getFunctionCounts("bar", 0x1234, Counts);
139   ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, std::move(E2)));
140 }
141 
142 // Profile data is copied from general.proftext
143 TEST_F(InstrProfTest, get_profile_summary) {
144   Writer.addRecord({"func1", 0x1234, {97531}}, Err);
145   Writer.addRecord({"func2", 0x1234, {0, 0}}, Err);
146   Writer.addRecord(
147       {"func3",
148        0x1234,
149        {2305843009213693952, 1152921504606846976, 576460752303423488,
150         288230376151711744, 144115188075855872, 72057594037927936}},
151       Err);
152   Writer.addRecord({"func4", 0x1234, {0}}, Err);
153   auto Profile = Writer.writeBuffer();
154   readProfile(std::move(Profile));
155 
156   auto VerifySummary = [](ProfileSummary &IPS) mutable {
157     ASSERT_EQ(ProfileSummary::PSK_Instr, IPS.getKind());
158     ASSERT_EQ(2305843009213693952U, IPS.getMaxFunctionCount());
159     ASSERT_EQ(2305843009213693952U, IPS.getMaxCount());
160     ASSERT_EQ(10U, IPS.getNumCounts());
161     ASSERT_EQ(4539628424389557499U, IPS.getTotalCount());
162     std::vector<ProfileSummaryEntry> &Details = IPS.getDetailedSummary();
163     uint32_t Cutoff = 800000;
164     auto Predicate = [&Cutoff](const ProfileSummaryEntry &PE) {
165       return PE.Cutoff == Cutoff;
166     };
167     auto EightyPerc = find_if(Details, Predicate);
168     Cutoff = 900000;
169     auto NinetyPerc = find_if(Details, Predicate);
170     Cutoff = 950000;
171     auto NinetyFivePerc = find_if(Details, Predicate);
172     Cutoff = 990000;
173     auto NinetyNinePerc = find_if(Details, Predicate);
174     ASSERT_EQ(576460752303423488U, EightyPerc->MinCount);
175     ASSERT_EQ(288230376151711744U, NinetyPerc->MinCount);
176     ASSERT_EQ(288230376151711744U, NinetyFivePerc->MinCount);
177     ASSERT_EQ(72057594037927936U, NinetyNinePerc->MinCount);
178   };
179   ProfileSummary &PS = Reader->getSummary();
180   VerifySummary(PS);
181 
182   // Test that conversion of summary to and from Metadata works.
183   LLVMContext Context;
184   Metadata *MD = PS.getMD(Context);
185   ASSERT_TRUE(MD);
186   ProfileSummary *PSFromMD = ProfileSummary::getFromMD(MD);
187   ASSERT_TRUE(PSFromMD);
188   VerifySummary(*PSFromMD);
189   delete PSFromMD;
190 
191   // Test that summary can be attached to and read back from module.
192   Module M("my_module", Context);
193   M.setProfileSummary(MD);
194   MD = M.getProfileSummary();
195   ASSERT_TRUE(MD);
196   PSFromMD = ProfileSummary::getFromMD(MD);
197   ASSERT_TRUE(PSFromMD);
198   VerifySummary(*PSFromMD);
199   delete PSFromMD;
200 }
201 
202 TEST_F(InstrProfTest, test_writer_merge) {
203   Writer.addRecord({"func1", 0x1234, {42}}, Err);
204 
205   InstrProfWriter Writer2;
206   Writer2.addRecord({"func2", 0x1234, {0, 0}}, Err);
207 
208   Writer.mergeRecordsFromWriter(std::move(Writer2), Err);
209 
210   auto Profile = Writer.writeBuffer();
211   readProfile(std::move(Profile));
212 
213   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("func1", 0x1234);
214   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
215   ASSERT_EQ(1U, R->Counts.size());
216   ASSERT_EQ(42U, R->Counts[0]);
217 
218   R = Reader->getInstrProfRecord("func2", 0x1234);
219   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
220   ASSERT_EQ(2U, R->Counts.size());
221   ASSERT_EQ(0U, R->Counts[0]);
222   ASSERT_EQ(0U, R->Counts[1]);
223 }
224 
225 static const char callee1[] = "callee1";
226 static const char callee2[] = "callee2";
227 static const char callee3[] = "callee3";
228 static const char callee4[] = "callee4";
229 static const char callee5[] = "callee5";
230 static const char callee6[] = "callee6";
231 
232 TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write) {
233   NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
234 
235   // 4 value sites.
236   Record1.reserveSites(IPVK_IndirectCallTarget, 4);
237   InstrProfValueData VD0[] = {
238       {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
239   Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
240   // No value profile data at the second site.
241   Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
242   InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
243   Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
244   InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
245   Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
246 
247   Writer.addRecord(std::move(Record1), Err);
248   Writer.addRecord({"callee1", 0x1235, {3, 4}}, Err);
249   Writer.addRecord({"callee2", 0x1235, {3, 4}}, Err);
250   Writer.addRecord({"callee3", 0x1235, {3, 4}}, Err);
251   auto Profile = Writer.writeBuffer();
252   readProfile(std::move(Profile));
253 
254   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
255   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
256   ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
257   ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
258   ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
259   ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
260   ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
261 
262   uint64_t TotalC;
263   std::unique_ptr<InstrProfValueData[]> VD =
264       R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC);
265 
266   ASSERT_EQ(3U, VD[0].Count);
267   ASSERT_EQ(2U, VD[1].Count);
268   ASSERT_EQ(1U, VD[2].Count);
269   ASSERT_EQ(6U, TotalC);
270 
271   ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
272   ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
273   ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
274 }
275 
276 TEST_P(MaybeSparseInstrProfTest, annotate_vp_data) {
277   NamedInstrProfRecord Record("caller", 0x1234, {1, 2});
278   Record.reserveSites(IPVK_IndirectCallTarget, 1);
279   InstrProfValueData VD0[] = {{1000, 1}, {2000, 2}, {3000, 3}, {5000, 5},
280                               {4000, 4}, {6000, 6}};
281   Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 6, nullptr);
282   Writer.addRecord(std::move(Record), Err);
283   auto Profile = Writer.writeBuffer();
284   readProfile(std::move(Profile));
285   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
286   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
287 
288   LLVMContext Ctx;
289   std::unique_ptr<Module> M(new Module("MyModule", Ctx));
290   FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
291                                         /*isVarArg=*/false);
292   Function *F =
293       Function::Create(FTy, Function::ExternalLinkage, "caller", M.get());
294   BasicBlock *BB = BasicBlock::Create(Ctx, "", F);
295 
296   IRBuilder<> Builder(BB);
297   BasicBlock *TBB = BasicBlock::Create(Ctx, "", F);
298   BasicBlock *FBB = BasicBlock::Create(Ctx, "", F);
299 
300   // Use branch instruction to annotate with value profile data for simplicity
301   Instruction *Inst = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
302   Instruction *Inst2 = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
303   annotateValueSite(*M, *Inst, R.get(), IPVK_IndirectCallTarget, 0);
304 
305   InstrProfValueData ValueData[5];
306   uint32_t N;
307   uint64_t T;
308   bool Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
309                                       ValueData, N, T);
310   ASSERT_TRUE(Res);
311   ASSERT_EQ(3U, N);
312   ASSERT_EQ(21U, T);
313   // The result should be sorted already:
314   ASSERT_EQ(6000U, ValueData[0].Value);
315   ASSERT_EQ(6U, ValueData[0].Count);
316   ASSERT_EQ(5000U, ValueData[1].Value);
317   ASSERT_EQ(5U, ValueData[1].Count);
318   ASSERT_EQ(4000U, ValueData[2].Value);
319   ASSERT_EQ(4U, ValueData[2].Count);
320   Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 1, ValueData,
321                                  N, T);
322   ASSERT_TRUE(Res);
323   ASSERT_EQ(1U, N);
324   ASSERT_EQ(21U, T);
325 
326   Res = getValueProfDataFromInst(*Inst2, IPVK_IndirectCallTarget, 5, ValueData,
327                                  N, T);
328   ASSERT_FALSE(Res);
329 
330   // Remove the MD_prof metadata
331   Inst->setMetadata(LLVMContext::MD_prof, 0);
332   // Annotate 5 records this time.
333   annotateValueSite(*M, *Inst, R.get(), IPVK_IndirectCallTarget, 0, 5);
334   Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
335                                       ValueData, N, T);
336   ASSERT_TRUE(Res);
337   ASSERT_EQ(5U, N);
338   ASSERT_EQ(21U, T);
339   ASSERT_EQ(6000U, ValueData[0].Value);
340   ASSERT_EQ(6U, ValueData[0].Count);
341   ASSERT_EQ(5000U, ValueData[1].Value);
342   ASSERT_EQ(5U, ValueData[1].Count);
343   ASSERT_EQ(4000U, ValueData[2].Value);
344   ASSERT_EQ(4U, ValueData[2].Count);
345   ASSERT_EQ(3000U, ValueData[3].Value);
346   ASSERT_EQ(3U, ValueData[3].Count);
347   ASSERT_EQ(2000U, ValueData[4].Value);
348   ASSERT_EQ(2U, ValueData[4].Count);
349 
350   // Remove the MD_prof metadata
351   Inst->setMetadata(LLVMContext::MD_prof, 0);
352   // Annotate with 4 records.
353   InstrProfValueData VD0Sorted[] = {{1000, 6}, {2000, 5}, {3000, 4}, {4000, 3},
354                               {5000, 2}, {6000, 1}};
355   annotateValueSite(*M, *Inst, makeArrayRef(VD0Sorted).slice(2), 10,
356                     IPVK_IndirectCallTarget, 5);
357   Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
358                                       ValueData, N, T);
359   ASSERT_TRUE(Res);
360   ASSERT_EQ(4U, N);
361   ASSERT_EQ(10U, T);
362   ASSERT_EQ(3000U, ValueData[0].Value);
363   ASSERT_EQ(4U, ValueData[0].Count);
364   ASSERT_EQ(4000U, ValueData[1].Value);
365   ASSERT_EQ(3U, ValueData[1].Count);
366   ASSERT_EQ(5000U, ValueData[2].Value);
367   ASSERT_EQ(2U, ValueData[2].Count);
368   ASSERT_EQ(6000U, ValueData[3].Value);
369   ASSERT_EQ(1U, ValueData[3].Count);
370 }
371 
372 TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_with_weight) {
373   NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
374 
375   // 4 value sites.
376   Record1.reserveSites(IPVK_IndirectCallTarget, 4);
377   InstrProfValueData VD0[] = {
378       {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
379   Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
380   // No value profile data at the second site.
381   Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
382   InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
383   Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
384   InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
385   Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
386 
387   Writer.addRecord(std::move(Record1), 10, Err);
388   Writer.addRecord({"callee1", 0x1235, {3, 4}}, Err);
389   Writer.addRecord({"callee2", 0x1235, {3, 4}}, Err);
390   Writer.addRecord({"callee3", 0x1235, {3, 4}}, Err);
391   auto Profile = Writer.writeBuffer();
392   readProfile(std::move(Profile));
393 
394   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
395   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
396   ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
397   ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
398   ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
399   ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
400   ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
401 
402   uint64_t TotalC;
403   std::unique_ptr<InstrProfValueData[]> VD =
404       R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC);
405   ASSERT_EQ(30U, VD[0].Count);
406   ASSERT_EQ(20U, VD[1].Count);
407   ASSERT_EQ(10U, VD[2].Count);
408   ASSERT_EQ(60U, TotalC);
409 
410   ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
411   ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
412   ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
413 }
414 
415 TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_big_endian) {
416   NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
417 
418   // 4 value sites.
419   Record1.reserveSites(IPVK_IndirectCallTarget, 4);
420   InstrProfValueData VD0[] = {
421       {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
422   Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
423   // No value profile data at the second site.
424   Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
425   InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
426   Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
427   InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
428   Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
429 
430   Writer.addRecord(std::move(Record1), Err);
431   Writer.addRecord({"callee1", 0x1235, {3, 4}}, Err);
432   Writer.addRecord({"callee2", 0x1235, {3, 4}}, Err);
433   Writer.addRecord({"callee3", 0x1235, {3, 4}}, Err);
434 
435   // Set big endian output.
436   Writer.setValueProfDataEndianness(support::big);
437 
438   auto Profile = Writer.writeBuffer();
439   readProfile(std::move(Profile));
440 
441   // Set big endian input.
442   Reader->setValueProfDataEndianness(support::big);
443 
444   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
445   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
446   ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
447   ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
448   ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
449   ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
450   ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
451 
452   std::unique_ptr<InstrProfValueData[]> VD =
453       R->getValueForSite(IPVK_IndirectCallTarget, 0);
454   ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
455   ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
456   ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
457 
458   // Restore little endian default:
459   Writer.setValueProfDataEndianness(support::little);
460 }
461 
462 TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge1) {
463   static const char caller[] = "caller";
464   NamedInstrProfRecord Record11(caller, 0x1234, {1, 2});
465   NamedInstrProfRecord Record12(caller, 0x1234, {1, 2});
466 
467   // 5 value sites.
468   Record11.reserveSites(IPVK_IndirectCallTarget, 5);
469   InstrProfValueData VD0[] = {{uint64_t(callee1), 1},
470                               {uint64_t(callee2), 2},
471                               {uint64_t(callee3), 3},
472                               {uint64_t(callee4), 4}};
473   Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 4, nullptr);
474 
475   // No value profile data at the second site.
476   Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
477 
478   InstrProfValueData VD2[] = {
479       {uint64_t(callee1), 1}, {uint64_t(callee2), 2}, {uint64_t(callee3), 3}};
480   Record11.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr);
481 
482   InstrProfValueData VD3[] = {{uint64_t(callee1), 1}};
483   Record11.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
484 
485   InstrProfValueData VD4[] = {{uint64_t(callee1), 1},
486                               {uint64_t(callee2), 2},
487                               {uint64_t(callee3), 3}};
488   Record11.addValueData(IPVK_IndirectCallTarget, 4, VD4, 3, nullptr);
489 
490   // A different record for the same caller.
491   Record12.reserveSites(IPVK_IndirectCallTarget, 5);
492   InstrProfValueData VD02[] = {{uint64_t(callee2), 5}, {uint64_t(callee3), 3}};
493   Record12.addValueData(IPVK_IndirectCallTarget, 0, VD02, 2, nullptr);
494 
495   // No value profile data at the second site.
496   Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
497 
498   InstrProfValueData VD22[] = {
499       {uint64_t(callee2), 1}, {uint64_t(callee3), 3}, {uint64_t(callee4), 4}};
500   Record12.addValueData(IPVK_IndirectCallTarget, 2, VD22, 3, nullptr);
501 
502   Record12.addValueData(IPVK_IndirectCallTarget, 3, nullptr, 0, nullptr);
503 
504   InstrProfValueData VD42[] = {{uint64_t(callee1), 1},
505                                {uint64_t(callee2), 2},
506                                {uint64_t(callee3), 3}};
507   Record12.addValueData(IPVK_IndirectCallTarget, 4, VD42, 3, nullptr);
508 
509   Writer.addRecord(std::move(Record11), Err);
510   // Merge profile data.
511   Writer.addRecord(std::move(Record12), Err);
512 
513   Writer.addRecord({callee1, 0x1235, {3, 4}}, Err);
514   Writer.addRecord({callee2, 0x1235, {3, 4}}, Err);
515   Writer.addRecord({callee3, 0x1235, {3, 4}}, Err);
516   Writer.addRecord({callee3, 0x1235, {3, 4}}, Err);
517   Writer.addRecord({callee4, 0x1235, {3, 5}}, Err);
518   auto Profile = Writer.writeBuffer();
519   readProfile(std::move(Profile));
520 
521   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
522   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
523   ASSERT_EQ(5U, R->getNumValueSites(IPVK_IndirectCallTarget));
524   ASSERT_EQ(4U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
525   ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
526   ASSERT_EQ(4U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
527   ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
528   ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 4));
529 
530   std::unique_ptr<InstrProfValueData[]> VD =
531       R->getValueForSite(IPVK_IndirectCallTarget, 0);
532   ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee2"));
533   ASSERT_EQ(7U, VD[0].Count);
534   ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee3"));
535   ASSERT_EQ(6U, VD[1].Count);
536   ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee4"));
537   ASSERT_EQ(4U, VD[2].Count);
538   ASSERT_EQ(StringRef((const char *)VD[3].Value, 7), StringRef("callee1"));
539   ASSERT_EQ(1U, VD[3].Count);
540 
541   std::unique_ptr<InstrProfValueData[]> VD_2(
542       R->getValueForSite(IPVK_IndirectCallTarget, 2));
543   ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee3"));
544   ASSERT_EQ(6U, VD_2[0].Count);
545   ASSERT_EQ(StringRef((const char *)VD_2[1].Value, 7), StringRef("callee4"));
546   ASSERT_EQ(4U, VD_2[1].Count);
547   ASSERT_EQ(StringRef((const char *)VD_2[2].Value, 7), StringRef("callee2"));
548   ASSERT_EQ(3U, VD_2[2].Count);
549   ASSERT_EQ(StringRef((const char *)VD_2[3].Value, 7), StringRef("callee1"));
550   ASSERT_EQ(1U, VD_2[3].Count);
551 
552   std::unique_ptr<InstrProfValueData[]> VD_3(
553       R->getValueForSite(IPVK_IndirectCallTarget, 3));
554   ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee1"));
555   ASSERT_EQ(1U, VD_3[0].Count);
556 
557   std::unique_ptr<InstrProfValueData[]> VD_4(
558       R->getValueForSite(IPVK_IndirectCallTarget, 4));
559   ASSERT_EQ(StringRef((const char *)VD_4[0].Value, 7), StringRef("callee3"));
560   ASSERT_EQ(6U, VD_4[0].Count);
561   ASSERT_EQ(StringRef((const char *)VD_4[1].Value, 7), StringRef("callee2"));
562   ASSERT_EQ(4U, VD_4[1].Count);
563   ASSERT_EQ(StringRef((const char *)VD_4[2].Value, 7), StringRef("callee1"));
564   ASSERT_EQ(2U, VD_4[2].Count);
565 }
566 
567 TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge1_saturation) {
568   static const char bar[] = "bar";
569 
570   const uint64_t Max = std::numeric_limits<uint64_t>::max();
571 
572   instrprof_error Result;
573   auto Err = [&](Error E) { Result = InstrProfError::take(std::move(E)); };
574   Result = instrprof_error::success;
575   Writer.addRecord({"foo", 0x1234, {1}}, Err);
576   ASSERT_EQ(Result, instrprof_error::success);
577 
578   // Verify counter overflow.
579   Result = instrprof_error::success;
580   Writer.addRecord({"foo", 0x1234, {Max}}, Err);
581   ASSERT_EQ(Result, instrprof_error::counter_overflow);
582 
583   Result = instrprof_error::success;
584   Writer.addRecord({bar, 0x9012, {8}}, Err);
585   ASSERT_EQ(Result, instrprof_error::success);
586 
587   NamedInstrProfRecord Record4("baz", 0x5678, {3, 4});
588   Record4.reserveSites(IPVK_IndirectCallTarget, 1);
589   InstrProfValueData VD4[] = {{uint64_t(bar), 1}};
590   Record4.addValueData(IPVK_IndirectCallTarget, 0, VD4, 1, nullptr);
591   Result = instrprof_error::success;
592   Writer.addRecord(std::move(Record4), Err);
593   ASSERT_EQ(Result, instrprof_error::success);
594 
595   // Verify value data counter overflow.
596   NamedInstrProfRecord Record5("baz", 0x5678, {5, 6});
597   Record5.reserveSites(IPVK_IndirectCallTarget, 1);
598   InstrProfValueData VD5[] = {{uint64_t(bar), Max}};
599   Record5.addValueData(IPVK_IndirectCallTarget, 0, VD5, 1, nullptr);
600   Result = instrprof_error::success;
601   Writer.addRecord(std::move(Record5), Err);
602   ASSERT_EQ(Result, instrprof_error::counter_overflow);
603 
604   auto Profile = Writer.writeBuffer();
605   readProfile(std::move(Profile));
606 
607   // Verify saturation of counts.
608   Expected<InstrProfRecord> ReadRecord1 =
609       Reader->getInstrProfRecord("foo", 0x1234);
610   EXPECT_THAT_ERROR(ReadRecord1.takeError(), Succeeded());
611   ASSERT_EQ(Max, ReadRecord1->Counts[0]);
612 
613   Expected<InstrProfRecord> ReadRecord2 =
614       Reader->getInstrProfRecord("baz", 0x5678);
615   ASSERT_TRUE(bool(ReadRecord2));
616   ASSERT_EQ(1U, ReadRecord2->getNumValueSites(IPVK_IndirectCallTarget));
617   std::unique_ptr<InstrProfValueData[]> VD =
618       ReadRecord2->getValueForSite(IPVK_IndirectCallTarget, 0);
619   ASSERT_EQ(StringRef("bar"), StringRef((const char *)VD[0].Value, 3));
620   ASSERT_EQ(Max, VD[0].Count);
621 }
622 
623 // This test tests that when there are too many values
624 // for a given site, the merged results are properly
625 // truncated.
626 TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge_site_trunc) {
627   static const char caller[] = "caller";
628 
629   NamedInstrProfRecord Record11(caller, 0x1234, {1, 2});
630   NamedInstrProfRecord Record12(caller, 0x1234, {1, 2});
631 
632   // 2 value sites.
633   Record11.reserveSites(IPVK_IndirectCallTarget, 2);
634   InstrProfValueData VD0[255];
635   for (int I = 0; I < 255; I++) {
636     VD0[I].Value = 2 * I;
637     VD0[I].Count = 2 * I + 1000;
638   }
639 
640   Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 255, nullptr);
641   Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
642 
643   Record12.reserveSites(IPVK_IndirectCallTarget, 2);
644   InstrProfValueData VD1[255];
645   for (int I = 0; I < 255; I++) {
646     VD1[I].Value = 2 * I + 1;
647     VD1[I].Count = 2 * I + 1001;
648   }
649 
650   Record12.addValueData(IPVK_IndirectCallTarget, 0, VD1, 255, nullptr);
651   Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
652 
653   Writer.addRecord(std::move(Record11), Err);
654   // Merge profile data.
655   Writer.addRecord(std::move(Record12), Err);
656 
657   auto Profile = Writer.writeBuffer();
658   readProfile(std::move(Profile));
659 
660   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
661   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
662   std::unique_ptr<InstrProfValueData[]> VD(
663       R->getValueForSite(IPVK_IndirectCallTarget, 0));
664   ASSERT_EQ(2U, R->getNumValueSites(IPVK_IndirectCallTarget));
665   ASSERT_EQ(255U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
666   for (unsigned I = 0; I < 255; I++) {
667     ASSERT_EQ(VD[I].Value, 509 - I);
668     ASSERT_EQ(VD[I].Count, 1509 - I);
669   }
670 }
671 
672 static void addValueProfData(InstrProfRecord &Record) {
673   Record.reserveSites(IPVK_IndirectCallTarget, 5);
674   InstrProfValueData VD0[] = {{uint64_t(callee1), 400},
675                               {uint64_t(callee2), 1000},
676                               {uint64_t(callee3), 500},
677                               {uint64_t(callee4), 300},
678                               {uint64_t(callee5), 100}};
679   Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 5, nullptr);
680   InstrProfValueData VD1[] = {{uint64_t(callee5), 800},
681                               {uint64_t(callee3), 1000},
682                               {uint64_t(callee2), 2500},
683                               {uint64_t(callee1), 1300}};
684   Record.addValueData(IPVK_IndirectCallTarget, 1, VD1, 4, nullptr);
685   InstrProfValueData VD2[] = {{uint64_t(callee6), 800},
686                               {uint64_t(callee3), 1000},
687                               {uint64_t(callee4), 5500}};
688   Record.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr);
689   InstrProfValueData VD3[] = {{uint64_t(callee2), 1800},
690                               {uint64_t(callee3), 2000}};
691   Record.addValueData(IPVK_IndirectCallTarget, 3, VD3, 2, nullptr);
692   Record.addValueData(IPVK_IndirectCallTarget, 4, nullptr, 0, nullptr);
693 }
694 
695 TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write) {
696   InstrProfRecord SrcRecord({1ULL << 31, 2});
697   addValueProfData(SrcRecord);
698   std::unique_ptr<ValueProfData> VPData =
699       ValueProfData::serializeFrom(SrcRecord);
700 
701   InstrProfRecord Record({1ULL << 31, 2});
702   VPData->deserializeTo(Record, nullptr);
703 
704   // Now read data from Record and sanity check the data
705   ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget));
706   ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
707   ASSERT_EQ(4U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
708   ASSERT_EQ(3U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
709   ASSERT_EQ(2U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
710   ASSERT_EQ(0U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 4));
711 
712   auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
713     return VD1.Count > VD2.Count;
714   };
715   std::unique_ptr<InstrProfValueData[]> VD_0(
716       Record.getValueForSite(IPVK_IndirectCallTarget, 0));
717   llvm::sort(&VD_0[0], &VD_0[5], Cmp);
718   ASSERT_EQ(StringRef((const char *)VD_0[0].Value, 7), StringRef("callee2"));
719   ASSERT_EQ(1000U, VD_0[0].Count);
720   ASSERT_EQ(StringRef((const char *)VD_0[1].Value, 7), StringRef("callee3"));
721   ASSERT_EQ(500U, VD_0[1].Count);
722   ASSERT_EQ(StringRef((const char *)VD_0[2].Value, 7), StringRef("callee1"));
723   ASSERT_EQ(400U, VD_0[2].Count);
724   ASSERT_EQ(StringRef((const char *)VD_0[3].Value, 7), StringRef("callee4"));
725   ASSERT_EQ(300U, VD_0[3].Count);
726   ASSERT_EQ(StringRef((const char *)VD_0[4].Value, 7), StringRef("callee5"));
727   ASSERT_EQ(100U, VD_0[4].Count);
728 
729   std::unique_ptr<InstrProfValueData[]> VD_1(
730       Record.getValueForSite(IPVK_IndirectCallTarget, 1));
731   llvm::sort(&VD_1[0], &VD_1[4], Cmp);
732   ASSERT_EQ(StringRef((const char *)VD_1[0].Value, 7), StringRef("callee2"));
733   ASSERT_EQ(2500U, VD_1[0].Count);
734   ASSERT_EQ(StringRef((const char *)VD_1[1].Value, 7), StringRef("callee1"));
735   ASSERT_EQ(1300U, VD_1[1].Count);
736   ASSERT_EQ(StringRef((const char *)VD_1[2].Value, 7), StringRef("callee3"));
737   ASSERT_EQ(1000U, VD_1[2].Count);
738   ASSERT_EQ(StringRef((const char *)VD_1[3].Value, 7), StringRef("callee5"));
739   ASSERT_EQ(800U, VD_1[3].Count);
740 
741   std::unique_ptr<InstrProfValueData[]> VD_2(
742       Record.getValueForSite(IPVK_IndirectCallTarget, 2));
743   llvm::sort(&VD_2[0], &VD_2[3], Cmp);
744   ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee4"));
745   ASSERT_EQ(5500U, VD_2[0].Count);
746   ASSERT_EQ(StringRef((const char *)VD_2[1].Value, 7), StringRef("callee3"));
747   ASSERT_EQ(1000U, VD_2[1].Count);
748   ASSERT_EQ(StringRef((const char *)VD_2[2].Value, 7), StringRef("callee6"));
749   ASSERT_EQ(800U, VD_2[2].Count);
750 
751   std::unique_ptr<InstrProfValueData[]> VD_3(
752       Record.getValueForSite(IPVK_IndirectCallTarget, 3));
753   llvm::sort(&VD_3[0], &VD_3[2], Cmp);
754   ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee3"));
755   ASSERT_EQ(2000U, VD_3[0].Count);
756   ASSERT_EQ(StringRef((const char *)VD_3[1].Value, 7), StringRef("callee2"));
757   ASSERT_EQ(1800U, VD_3[1].Count);
758 }
759 
760 TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write_mapping) {
761 
762   NamedInstrProfRecord SrcRecord("caller", 0x1234, {1ULL << 31, 2});
763   addValueProfData(SrcRecord);
764   std::unique_ptr<ValueProfData> VPData =
765       ValueProfData::serializeFrom(SrcRecord);
766 
767   NamedInstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2});
768   InstrProfSymtab Symtab;
769   Symtab.mapAddress(uint64_t(callee1), 0x1000ULL);
770   Symtab.mapAddress(uint64_t(callee2), 0x2000ULL);
771   Symtab.mapAddress(uint64_t(callee3), 0x3000ULL);
772   Symtab.mapAddress(uint64_t(callee4), 0x4000ULL);
773   // Missing mapping for callee5
774 
775   VPData->deserializeTo(Record, &Symtab);
776 
777   // Now read data from Record and sanity check the data
778   ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget));
779   ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
780 
781   auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
782     return VD1.Count > VD2.Count;
783   };
784   std::unique_ptr<InstrProfValueData[]> VD_0(
785       Record.getValueForSite(IPVK_IndirectCallTarget, 0));
786   llvm::sort(&VD_0[0], &VD_0[5], Cmp);
787   ASSERT_EQ(VD_0[0].Value, 0x2000ULL);
788   ASSERT_EQ(1000U, VD_0[0].Count);
789   ASSERT_EQ(VD_0[1].Value, 0x3000ULL);
790   ASSERT_EQ(500U, VD_0[1].Count);
791   ASSERT_EQ(VD_0[2].Value, 0x1000ULL);
792   ASSERT_EQ(400U, VD_0[2].Count);
793 
794   // callee5 does not have a mapped value -- default to 0.
795   ASSERT_EQ(VD_0[4].Value, 0ULL);
796 }
797 
798 TEST_P(MaybeSparseInstrProfTest, get_max_function_count) {
799   Writer.addRecord({"foo", 0x1234, {1ULL << 31, 2}}, Err);
800   Writer.addRecord({"bar", 0, {1ULL << 63}}, Err);
801   Writer.addRecord({"baz", 0x5678, {0, 0, 0, 0}}, Err);
802   auto Profile = Writer.writeBuffer();
803   readProfile(std::move(Profile));
804 
805   ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount());
806 }
807 
808 TEST_P(MaybeSparseInstrProfTest, get_weighted_function_counts) {
809   Writer.addRecord({"foo", 0x1234, {1, 2}}, 3, Err);
810   Writer.addRecord({"foo", 0x1235, {3, 4}}, 5, Err);
811   auto Profile = Writer.writeBuffer();
812   readProfile(std::move(Profile));
813 
814   std::vector<uint64_t> Counts;
815   EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1234, Counts),
816                     Succeeded());
817   ASSERT_EQ(2U, Counts.size());
818   ASSERT_EQ(3U, Counts[0]);
819   ASSERT_EQ(6U, Counts[1]);
820 
821   EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1235, Counts),
822                     Succeeded());
823   ASSERT_EQ(2U, Counts.size());
824   ASSERT_EQ(15U, Counts[0]);
825   ASSERT_EQ(20U, Counts[1]);
826 }
827 
828 // Testing symtab creator interface used by indexed profile reader.
829 TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_test) {
830   std::vector<StringRef> FuncNames;
831   FuncNames.push_back("func1");
832   FuncNames.push_back("func2");
833   FuncNames.push_back("func3");
834   FuncNames.push_back("bar1");
835   FuncNames.push_back("bar2");
836   FuncNames.push_back("bar3");
837   InstrProfSymtab Symtab;
838   EXPECT_THAT_ERROR(Symtab.create(FuncNames), Succeeded());
839   StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
840   ASSERT_EQ(StringRef("func1"), R);
841   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
842   ASSERT_EQ(StringRef("func2"), R);
843   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
844   ASSERT_EQ(StringRef("func3"), R);
845   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
846   ASSERT_EQ(StringRef("bar1"), R);
847   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
848   ASSERT_EQ(StringRef("bar2"), R);
849   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
850   ASSERT_EQ(StringRef("bar3"), R);
851 
852   // negative tests
853   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar4"));
854   ASSERT_EQ(StringRef(), R);
855   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("foo4"));
856   ASSERT_EQ(StringRef(), R);
857 
858   // Now incrementally update the symtab
859   EXPECT_THAT_ERROR(Symtab.addFuncName("blah_1"), Succeeded());
860   EXPECT_THAT_ERROR(Symtab.addFuncName("blah_2"), Succeeded());
861   EXPECT_THAT_ERROR(Symtab.addFuncName("blah_3"), Succeeded());
862 
863   // Check again
864   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_1"));
865   ASSERT_EQ(StringRef("blah_1"), R);
866   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_2"));
867   ASSERT_EQ(StringRef("blah_2"), R);
868   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_3"));
869   ASSERT_EQ(StringRef("blah_3"), R);
870   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
871   ASSERT_EQ(StringRef("func1"), R);
872   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
873   ASSERT_EQ(StringRef("func2"), R);
874   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
875   ASSERT_EQ(StringRef("func3"), R);
876   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
877   ASSERT_EQ(StringRef("bar1"), R);
878   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
879   ASSERT_EQ(StringRef("bar2"), R);
880   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
881   ASSERT_EQ(StringRef("bar3"), R);
882 }
883 
884 // Test that we get an error when creating a bogus symtab.
885 TEST_P(MaybeSparseInstrProfTest, instr_prof_bogus_symtab_empty_func_name) {
886   InstrProfSymtab Symtab;
887   EXPECT_TRUE(ErrorEquals(instrprof_error::malformed, Symtab.addFuncName("")));
888 }
889 
890 // Testing symtab creator interface used by value profile transformer.
891 TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_module_test) {
892   LLVMContext Ctx;
893   std::unique_ptr<Module> M = llvm::make_unique<Module>("MyModule.cpp", Ctx);
894   FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
895                                         /*isVarArg=*/false);
896   Function::Create(FTy, Function::ExternalLinkage, "Gfoo", M.get());
897   Function::Create(FTy, Function::ExternalLinkage, "Gblah", M.get());
898   Function::Create(FTy, Function::ExternalLinkage, "Gbar", M.get());
899   Function::Create(FTy, Function::InternalLinkage, "Ifoo", M.get());
900   Function::Create(FTy, Function::InternalLinkage, "Iblah", M.get());
901   Function::Create(FTy, Function::InternalLinkage, "Ibar", M.get());
902   Function::Create(FTy, Function::PrivateLinkage, "Pfoo", M.get());
903   Function::Create(FTy, Function::PrivateLinkage, "Pblah", M.get());
904   Function::Create(FTy, Function::PrivateLinkage, "Pbar", M.get());
905   Function::Create(FTy, Function::WeakODRLinkage, "Wfoo", M.get());
906   Function::Create(FTy, Function::WeakODRLinkage, "Wblah", M.get());
907   Function::Create(FTy, Function::WeakODRLinkage, "Wbar", M.get());
908 
909   InstrProfSymtab ProfSymtab;
910   EXPECT_THAT_ERROR(ProfSymtab.create(*M), Succeeded());
911 
912   StringRef Funcs[] = {"Gfoo", "Gblah", "Gbar", "Ifoo", "Iblah", "Ibar",
913                        "Pfoo", "Pblah", "Pbar", "Wfoo", "Wblah", "Wbar"};
914 
915   for (unsigned I = 0; I < sizeof(Funcs) / sizeof(*Funcs); I++) {
916     Function *F = M->getFunction(Funcs[I]);
917     ASSERT_TRUE(F != nullptr);
918     std::string PGOName = getPGOFuncName(*F);
919     uint64_t Key = IndexedInstrProf::ComputeHash(PGOName);
920     ASSERT_EQ(StringRef(PGOName),
921               ProfSymtab.getFuncName(Key));
922     ASSERT_EQ(StringRef(Funcs[I]), ProfSymtab.getOrigFuncName(Key));
923   }
924 }
925 
926 // Testing symtab serialization and creator/deserialization interface
927 // used by coverage map reader, and raw profile reader.
928 TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_compression_test) {
929   std::vector<std::string> FuncNames1;
930   std::vector<std::string> FuncNames2;
931   for (int I = 0; I < 3; I++) {
932     std::string str;
933     raw_string_ostream OS(str);
934     OS << "func_" << I;
935     FuncNames1.push_back(OS.str());
936     str.clear();
937     OS << "f oooooooooooooo_" << I;
938     FuncNames1.push_back(OS.str());
939     str.clear();
940     OS << "BAR_" << I;
941     FuncNames2.push_back(OS.str());
942     str.clear();
943     OS << "BlahblahBlahblahBar_" << I;
944     FuncNames2.push_back(OS.str());
945   }
946 
947   for (bool DoCompression : {false, true}) {
948     // Compressing:
949     std::string FuncNameStrings1;
950     EXPECT_THAT_ERROR(collectPGOFuncNameStrings(
951                           FuncNames1, (DoCompression && zlib::isAvailable()),
952                           FuncNameStrings1),
953                       Succeeded());
954 
955     // Compressing:
956     std::string FuncNameStrings2;
957     EXPECT_THAT_ERROR(collectPGOFuncNameStrings(
958                           FuncNames2, (DoCompression && zlib::isAvailable()),
959                           FuncNameStrings2),
960                       Succeeded());
961 
962     for (int Padding = 0; Padding < 2; Padding++) {
963       // Join with paddings :
964       std::string FuncNameStrings = FuncNameStrings1;
965       for (int P = 0; P < Padding; P++) {
966         FuncNameStrings.push_back('\0');
967       }
968       FuncNameStrings += FuncNameStrings2;
969 
970       // Now decompress:
971       InstrProfSymtab Symtab;
972       EXPECT_THAT_ERROR(Symtab.create(StringRef(FuncNameStrings)), Succeeded());
973 
974       // Now do the checks:
975       // First sampling some data points:
976       StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[0]));
977       ASSERT_EQ(StringRef("func_0"), R);
978       R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[1]));
979       ASSERT_EQ(StringRef("f oooooooooooooo_0"), R);
980       for (int I = 0; I < 3; I++) {
981         std::string N[4];
982         N[0] = FuncNames1[2 * I];
983         N[1] = FuncNames1[2 * I + 1];
984         N[2] = FuncNames2[2 * I];
985         N[3] = FuncNames2[2 * I + 1];
986         for (int J = 0; J < 4; J++) {
987           StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(N[J]));
988           ASSERT_EQ(StringRef(N[J]), R);
989         }
990       }
991     }
992   }
993 }
994 
995 TEST_P(MaybeSparseInstrProfTest, remapping_test) {
996   Writer.addRecord({"_Z3fooi", 0x1234, {1, 2, 3, 4}}, Err);
997   Writer.addRecord({"file:_Z3barf", 0x567, {5, 6, 7}}, Err);
998   auto Profile = Writer.writeBuffer();
999   readProfile(std::move(Profile), llvm::MemoryBuffer::getMemBuffer(R"(
1000     type i l
1001     name 3bar 4quux
1002   )"));
1003 
1004   std::vector<uint64_t> Counts;
1005   for (StringRef FooName : {"_Z3fooi", "_Z3fool"}) {
1006     EXPECT_THAT_ERROR(Reader->getFunctionCounts(FooName, 0x1234, Counts),
1007                       Succeeded());
1008     ASSERT_EQ(4u, Counts.size());
1009     EXPECT_EQ(1u, Counts[0]);
1010     EXPECT_EQ(2u, Counts[1]);
1011     EXPECT_EQ(3u, Counts[2]);
1012     EXPECT_EQ(4u, Counts[3]);
1013   }
1014 
1015   for (StringRef BarName : {"file:_Z3barf", "file:_Z4quuxf"}) {
1016     EXPECT_THAT_ERROR(Reader->getFunctionCounts(BarName, 0x567, Counts),
1017                       Succeeded());
1018     ASSERT_EQ(3u, Counts.size());
1019     EXPECT_EQ(5u, Counts[0]);
1020     EXPECT_EQ(6u, Counts[1]);
1021     EXPECT_EQ(7u, Counts[2]);
1022   }
1023 
1024   for (StringRef BadName : {"_Z3foof", "_Z4quuxi", "_Z3barl", "", "_ZZZ",
1025                             "_Z3barf", "otherfile:_Z4quuxf"}) {
1026     EXPECT_THAT_ERROR(Reader->getFunctionCounts(BadName, 0x1234, Counts),
1027                       Failed());
1028     EXPECT_THAT_ERROR(Reader->getFunctionCounts(BadName, 0x567, Counts),
1029                       Failed());
1030   }
1031 }
1032 
1033 TEST_F(SparseInstrProfTest, preserve_no_records) {
1034   Writer.addRecord({"foo", 0x1234, {0}}, Err);
1035   Writer.addRecord({"bar", 0x4321, {0, 0}}, Err);
1036   Writer.addRecord({"baz", 0x4321, {0, 0, 0}}, Err);
1037 
1038   auto Profile = Writer.writeBuffer();
1039   readProfile(std::move(Profile));
1040 
1041   auto I = Reader->begin(), E = Reader->end();
1042   ASSERT_TRUE(I == E);
1043 }
1044 
1045 INSTANTIATE_TEST_CASE_P(MaybeSparse, MaybeSparseInstrProfTest,
1046                         ::testing::Bool(),);
1047 
1048 } // end anonymous namespace
1049