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