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