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