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