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