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 "llvm/Testing/Support/Error.h"
18 #include "llvm/Testing/Support/SupportHelpers.h"
19 #include "gtest/gtest.h"
20 #include <cstdarg>
21 
22 using namespace llvm;
23 
24 LLVM_NODISCARD static ::testing::AssertionResult
25 ErrorEquals(instrprof_error Expected, Error E) {
26   instrprof_error Found;
27   std::string FoundMsg;
28   handleAllErrors(std::move(E), [&](const InstrProfError &IPE) {
29     Found = IPE.get();
30     FoundMsg = IPE.message();
31   });
32   if (Expected == Found)
33     return ::testing::AssertionSuccess();
34   return ::testing::AssertionFailure() << "error: " << FoundMsg << "\n";
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     EXPECT_THAT_ERROR(ReaderOrErr.takeError(), Succeeded());
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   EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1234, {1, 2, 3, 4}}),
69                     Succeeded());
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   EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1234, {1, 2}}), Succeeded());
87   EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1235, {3, 4}}), Succeeded());
88   auto Profile = Writer.writeBuffer();
89   readProfile(std::move(Profile));
90 
91   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("foo", 0x1234);
92   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
93   ASSERT_EQ(2U, R->Counts.size());
94   ASSERT_EQ(1U, R->Counts[0]);
95   ASSERT_EQ(2U, R->Counts[1]);
96 
97   R = Reader->getInstrProfRecord("foo", 0x1235);
98   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
99   ASSERT_EQ(2U, R->Counts.size());
100   ASSERT_EQ(3U, R->Counts[0]);
101   ASSERT_EQ(4U, R->Counts[1]);
102 
103   R = Reader->getInstrProfRecord("foo", 0x5678);
104   ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, R.takeError()));
105 
106   R = Reader->getInstrProfRecord("bar", 0x1234);
107   ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, R.takeError()));
108 }
109 
110 TEST_P(MaybeSparseInstrProfTest, get_function_counts) {
111   EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1234, {1, 2}}), Succeeded());
112   EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1235, {3, 4}}), Succeeded());
113   auto Profile = Writer.writeBuffer();
114   readProfile(std::move(Profile));
115 
116   std::vector<uint64_t> Counts;
117   EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1234, Counts),
118                     Succeeded());
119   ASSERT_EQ(2U, Counts.size());
120   ASSERT_EQ(1U, Counts[0]);
121   ASSERT_EQ(2U, Counts[1]);
122 
123   EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1235, Counts),
124                     Succeeded());
125   ASSERT_EQ(2U, Counts.size());
126   ASSERT_EQ(3U, Counts[0]);
127   ASSERT_EQ(4U, Counts[1]);
128 
129   Error E1 = Reader->getFunctionCounts("foo", 0x5678, Counts);
130   ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, std::move(E1)));
131 
132   Error E2 = Reader->getFunctionCounts("bar", 0x1234, Counts);
133   ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, std::move(E2)));
134 }
135 
136 // Profile data is copied from general.proftext
137 TEST_F(InstrProfTest, get_profile_summary) {
138   EXPECT_THAT_ERROR(Writer.addRecord({"func1", 0x1234, {97531}}), Succeeded());
139   EXPECT_THAT_ERROR(Writer.addRecord({"func2", 0x1234, {0, 0}}), Succeeded());
140   EXPECT_THAT_ERROR(Writer.addRecord({"func3",
141                                       0x1234,
142                                       {2305843009213693952, 1152921504606846976,
143                                        576460752303423488, 288230376151711744,
144                                        144115188075855872, 72057594037927936}}),
145                     Succeeded());
146   EXPECT_THAT_ERROR(Writer.addRecord({"func4", 0x1234, {0}}), Succeeded());
147   auto Profile = Writer.writeBuffer();
148   readProfile(std::move(Profile));
149 
150   auto VerifySummary = [](ProfileSummary &IPS) mutable {
151     ASSERT_EQ(ProfileSummary::PSK_Instr, IPS.getKind());
152     ASSERT_EQ(2305843009213693952U, IPS.getMaxFunctionCount());
153     ASSERT_EQ(2305843009213693952U, IPS.getMaxCount());
154     ASSERT_EQ(10U, IPS.getNumCounts());
155     ASSERT_EQ(4539628424389557499U, IPS.getTotalCount());
156     std::vector<ProfileSummaryEntry> &Details = IPS.getDetailedSummary();
157     uint32_t Cutoff = 800000;
158     auto Predicate = [&Cutoff](const ProfileSummaryEntry &PE) {
159       return PE.Cutoff == Cutoff;
160     };
161     auto EightyPerc = find_if(Details, Predicate);
162     Cutoff = 900000;
163     auto NinetyPerc = find_if(Details, Predicate);
164     Cutoff = 950000;
165     auto NinetyFivePerc = find_if(Details, Predicate);
166     Cutoff = 990000;
167     auto NinetyNinePerc = find_if(Details, Predicate);
168     ASSERT_EQ(576460752303423488U, EightyPerc->MinCount);
169     ASSERT_EQ(288230376151711744U, NinetyPerc->MinCount);
170     ASSERT_EQ(288230376151711744U, NinetyFivePerc->MinCount);
171     ASSERT_EQ(72057594037927936U, NinetyNinePerc->MinCount);
172   };
173   ProfileSummary &PS = Reader->getSummary();
174   VerifySummary(PS);
175 
176   // Test that conversion of summary to and from Metadata works.
177   LLVMContext Context;
178   Metadata *MD = PS.getMD(Context);
179   ASSERT_TRUE(MD);
180   ProfileSummary *PSFromMD = ProfileSummary::getFromMD(MD);
181   ASSERT_TRUE(PSFromMD);
182   VerifySummary(*PSFromMD);
183   delete PSFromMD;
184 
185   // Test that summary can be attached to and read back from module.
186   Module M("my_module", Context);
187   M.setProfileSummary(MD);
188   MD = M.getProfileSummary();
189   ASSERT_TRUE(MD);
190   PSFromMD = ProfileSummary::getFromMD(MD);
191   ASSERT_TRUE(PSFromMD);
192   VerifySummary(*PSFromMD);
193   delete PSFromMD;
194 }
195 
196 TEST_F(InstrProfTest, test_writer_merge) {
197   EXPECT_THAT_ERROR(Writer.addRecord({"func1", 0x1234, {42}}), Succeeded());
198 
199   InstrProfWriter Writer2;
200   EXPECT_THAT_ERROR(Writer2.addRecord({"func2", 0x1234, {0, 0}}), Succeeded());
201 
202   EXPECT_THAT_ERROR(Writer.mergeRecordsFromWriter(std::move(Writer2)),
203                     Succeeded());
204 
205   auto Profile = Writer.writeBuffer();
206   readProfile(std::move(Profile));
207 
208   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("func1", 0x1234);
209   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
210   ASSERT_EQ(1U, R->Counts.size());
211   ASSERT_EQ(42U, R->Counts[0]);
212 
213   R = Reader->getInstrProfRecord("func2", 0x1234);
214   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
215   ASSERT_EQ(2U, R->Counts.size());
216   ASSERT_EQ(0U, R->Counts[0]);
217   ASSERT_EQ(0U, R->Counts[1]);
218 }
219 
220 static const char callee1[] = "callee1";
221 static const char callee2[] = "callee2";
222 static const char callee3[] = "callee3";
223 static const char callee4[] = "callee4";
224 static const char callee5[] = "callee5";
225 static const char callee6[] = "callee6";
226 
227 TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write) {
228   NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
229 
230   // 4 value sites.
231   Record1.reserveSites(IPVK_IndirectCallTarget, 4);
232   InstrProfValueData VD0[] = {
233       {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
234   Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
235   // No value profile data at the second site.
236   Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
237   InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
238   Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
239   InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
240   Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
241 
242   EXPECT_THAT_ERROR(Writer.addRecord(std::move(Record1)), Succeeded());
243   EXPECT_THAT_ERROR(Writer.addRecord({"callee1", 0x1235, {3, 4}}), Succeeded());
244   EXPECT_THAT_ERROR(Writer.addRecord({"callee2", 0x1235, {3, 4}}), Succeeded());
245   EXPECT_THAT_ERROR(Writer.addRecord({"callee3", 0x1235, {3, 4}}), Succeeded());
246   auto Profile = Writer.writeBuffer();
247   readProfile(std::move(Profile));
248 
249   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
250   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
251   ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
252   ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
253   ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
254   ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
255   ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
256 
257   uint64_t TotalC;
258   std::unique_ptr<InstrProfValueData[]> VD =
259       R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC);
260 
261   ASSERT_EQ(3U, VD[0].Count);
262   ASSERT_EQ(2U, VD[1].Count);
263   ASSERT_EQ(1U, VD[2].Count);
264   ASSERT_EQ(6U, TotalC);
265 
266   ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
267   ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
268   ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
269 }
270 
271 TEST_P(MaybeSparseInstrProfTest, annotate_vp_data) {
272   NamedInstrProfRecord Record("caller", 0x1234, {1, 2});
273   Record.reserveSites(IPVK_IndirectCallTarget, 1);
274   InstrProfValueData VD0[] = {{1000, 1}, {2000, 2}, {3000, 3}, {5000, 5},
275                               {4000, 4}, {6000, 6}};
276   Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 6, nullptr);
277   EXPECT_THAT_ERROR(Writer.addRecord(std::move(Record)), Succeeded());
278   auto Profile = Writer.writeBuffer();
279   readProfile(std::move(Profile));
280   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
281   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
282 
283   LLVMContext Ctx;
284   std::unique_ptr<Module> M(new Module("MyModule", Ctx));
285   FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
286                                         /*isVarArg=*/false);
287   Function *F =
288       Function::Create(FTy, Function::ExternalLinkage, "caller", M.get());
289   BasicBlock *BB = BasicBlock::Create(Ctx, "", F);
290 
291   IRBuilder<> Builder(BB);
292   BasicBlock *TBB = BasicBlock::Create(Ctx, "", F);
293   BasicBlock *FBB = BasicBlock::Create(Ctx, "", F);
294 
295   // Use branch instruction to annotate with value profile data for simplicity
296   Instruction *Inst = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
297   Instruction *Inst2 = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
298   annotateValueSite(*M, *Inst, R.get(), IPVK_IndirectCallTarget, 0);
299 
300   InstrProfValueData ValueData[5];
301   uint32_t N;
302   uint64_t T;
303   bool Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
304                                       ValueData, N, T);
305   ASSERT_TRUE(Res);
306   ASSERT_EQ(3U, N);
307   ASSERT_EQ(21U, T);
308   // The result should be sorted already:
309   ASSERT_EQ(6000U, ValueData[0].Value);
310   ASSERT_EQ(6U, ValueData[0].Count);
311   ASSERT_EQ(5000U, ValueData[1].Value);
312   ASSERT_EQ(5U, ValueData[1].Count);
313   ASSERT_EQ(4000U, ValueData[2].Value);
314   ASSERT_EQ(4U, ValueData[2].Count);
315   Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 1, ValueData,
316                                  N, T);
317   ASSERT_TRUE(Res);
318   ASSERT_EQ(1U, N);
319   ASSERT_EQ(21U, T);
320 
321   Res = getValueProfDataFromInst(*Inst2, IPVK_IndirectCallTarget, 5, ValueData,
322                                  N, T);
323   ASSERT_FALSE(Res);
324 
325   // Remove the MD_prof metadata
326   Inst->setMetadata(LLVMContext::MD_prof, 0);
327   // Annotate 5 records this time.
328   annotateValueSite(*M, *Inst, R.get(), IPVK_IndirectCallTarget, 0, 5);
329   Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
330                                       ValueData, N, T);
331   ASSERT_TRUE(Res);
332   ASSERT_EQ(5U, N);
333   ASSERT_EQ(21U, T);
334   ASSERT_EQ(6000U, ValueData[0].Value);
335   ASSERT_EQ(6U, ValueData[0].Count);
336   ASSERT_EQ(5000U, ValueData[1].Value);
337   ASSERT_EQ(5U, ValueData[1].Count);
338   ASSERT_EQ(4000U, ValueData[2].Value);
339   ASSERT_EQ(4U, ValueData[2].Count);
340   ASSERT_EQ(3000U, ValueData[3].Value);
341   ASSERT_EQ(3U, ValueData[3].Count);
342   ASSERT_EQ(2000U, ValueData[4].Value);
343   ASSERT_EQ(2U, ValueData[4].Count);
344 
345   // Remove the MD_prof metadata
346   Inst->setMetadata(LLVMContext::MD_prof, 0);
347   // Annotate with 4 records.
348   InstrProfValueData VD0Sorted[] = {{1000, 6}, {2000, 5}, {3000, 4}, {4000, 3},
349                               {5000, 2}, {6000, 1}};
350   annotateValueSite(*M, *Inst, makeArrayRef(VD0Sorted).slice(2), 10,
351                     IPVK_IndirectCallTarget, 5);
352   Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
353                                       ValueData, N, T);
354   ASSERT_TRUE(Res);
355   ASSERT_EQ(4U, N);
356   ASSERT_EQ(10U, T);
357   ASSERT_EQ(3000U, ValueData[0].Value);
358   ASSERT_EQ(4U, ValueData[0].Count);
359   ASSERT_EQ(4000U, ValueData[1].Value);
360   ASSERT_EQ(3U, ValueData[1].Count);
361   ASSERT_EQ(5000U, ValueData[2].Value);
362   ASSERT_EQ(2U, ValueData[2].Count);
363   ASSERT_EQ(6000U, ValueData[3].Value);
364   ASSERT_EQ(1U, ValueData[3].Count);
365 }
366 
367 TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_with_weight) {
368   NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
369 
370   // 4 value sites.
371   Record1.reserveSites(IPVK_IndirectCallTarget, 4);
372   InstrProfValueData VD0[] = {
373       {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
374   Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
375   // No value profile data at the second site.
376   Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
377   InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
378   Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
379   InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
380   Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
381 
382   EXPECT_THAT_ERROR(Writer.addRecord(std::move(Record1), 10), Succeeded());
383   EXPECT_THAT_ERROR(Writer.addRecord({"callee1", 0x1235, {3, 4}}), Succeeded());
384   EXPECT_THAT_ERROR(Writer.addRecord({"callee2", 0x1235, {3, 4}}), Succeeded());
385   EXPECT_THAT_ERROR(Writer.addRecord({"callee3", 0x1235, {3, 4}}), Succeeded());
386   auto Profile = Writer.writeBuffer();
387   readProfile(std::move(Profile));
388 
389   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
390   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
391   ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
392   ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
393   ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
394   ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
395   ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
396 
397   uint64_t TotalC;
398   std::unique_ptr<InstrProfValueData[]> VD =
399       R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC);
400   ASSERT_EQ(30U, VD[0].Count);
401   ASSERT_EQ(20U, VD[1].Count);
402   ASSERT_EQ(10U, VD[2].Count);
403   ASSERT_EQ(60U, TotalC);
404 
405   ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
406   ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
407   ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
408 }
409 
410 TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_big_endian) {
411   NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
412 
413   // 4 value sites.
414   Record1.reserveSites(IPVK_IndirectCallTarget, 4);
415   InstrProfValueData VD0[] = {
416       {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
417   Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
418   // No value profile data at the second site.
419   Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
420   InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
421   Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
422   InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
423   Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
424 
425   EXPECT_THAT_ERROR(Writer.addRecord(std::move(Record1)), Succeeded());
426   EXPECT_THAT_ERROR(Writer.addRecord({"callee1", 0x1235, {3, 4}}), Succeeded());
427   EXPECT_THAT_ERROR(Writer.addRecord({"callee2", 0x1235, {3, 4}}), Succeeded());
428   EXPECT_THAT_ERROR(Writer.addRecord({"callee3", 0x1235, {3, 4}}), Succeeded());
429 
430   // Set big endian output.
431   Writer.setValueProfDataEndianness(support::big);
432 
433   auto Profile = Writer.writeBuffer();
434   readProfile(std::move(Profile));
435 
436   // Set big endian input.
437   Reader->setValueProfDataEndianness(support::big);
438 
439   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
440   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
441   ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
442   ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
443   ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
444   ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
445   ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
446 
447   std::unique_ptr<InstrProfValueData[]> VD =
448       R->getValueForSite(IPVK_IndirectCallTarget, 0);
449   ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
450   ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
451   ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
452 
453   // Restore little endian default:
454   Writer.setValueProfDataEndianness(support::little);
455 }
456 
457 TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge1) {
458   static const char caller[] = "caller";
459   NamedInstrProfRecord Record11(caller, 0x1234, {1, 2});
460   NamedInstrProfRecord Record12(caller, 0x1234, {1, 2});
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 different 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   EXPECT_THAT_ERROR(Writer.addRecord(std::move(Record11)), Succeeded());
505   // Merge profile data.
506   EXPECT_THAT_ERROR(Writer.addRecord(std::move(Record12)), Succeeded());
507 
508   EXPECT_THAT_ERROR(Writer.addRecord({callee1, 0x1235, {3, 4}}), Succeeded());
509   EXPECT_THAT_ERROR(Writer.addRecord({callee2, 0x1235, {3, 4}}), Succeeded());
510   EXPECT_THAT_ERROR(Writer.addRecord({callee3, 0x1235, {3, 4}}), Succeeded());
511   EXPECT_THAT_ERROR(Writer.addRecord({callee3, 0x1235, {3, 4}}), Succeeded());
512   EXPECT_THAT_ERROR(Writer.addRecord({callee4, 0x1235, {3, 5}}), Succeeded());
513   auto Profile = Writer.writeBuffer();
514   readProfile(std::move(Profile));
515 
516   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
517   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
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   auto Result1 = Writer.addRecord({"foo", 0x1234, {1}});
568   ASSERT_EQ(InstrProfError::take(std::move(Result1)),
569             instrprof_error::success);
570 
571   // Verify counter overflow.
572   auto Result2 = Writer.addRecord({"foo", 0x1234, {Max}});
573   ASSERT_EQ(InstrProfError::take(std::move(Result2)),
574             instrprof_error::counter_overflow);
575 
576   auto Result3 = Writer.addRecord({bar, 0x9012, {8}});
577   ASSERT_EQ(InstrProfError::take(std::move(Result3)),
578             instrprof_error::success);
579 
580   NamedInstrProfRecord 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(InstrProfError::take(std::move(Result4)),
586             instrprof_error::success);
587 
588   // Verify value data counter overflow.
589   NamedInstrProfRecord Record5("baz", 0x5678, {5, 6});
590   Record5.reserveSites(IPVK_IndirectCallTarget, 1);
591   InstrProfValueData VD5[] = {{uint64_t(bar), Max}};
592   Record5.addValueData(IPVK_IndirectCallTarget, 0, VD5, 1, nullptr);
593   auto Result5 = Writer.addRecord(std::move(Record5));
594   ASSERT_EQ(InstrProfError::take(std::move(Result5)),
595             instrprof_error::counter_overflow);
596 
597   auto Profile = Writer.writeBuffer();
598   readProfile(std::move(Profile));
599 
600   // Verify saturation of counts.
601   Expected<InstrProfRecord> ReadRecord1 =
602       Reader->getInstrProfRecord("foo", 0x1234);
603   EXPECT_THAT_ERROR(ReadRecord1.takeError(), Succeeded());
604   ASSERT_EQ(Max, ReadRecord1->Counts[0]);
605 
606   Expected<InstrProfRecord> ReadRecord2 =
607       Reader->getInstrProfRecord("baz", 0x5678);
608   ASSERT_TRUE(bool(ReadRecord2));
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   NamedInstrProfRecord Record11(caller, 0x1234, {1, 2});
623   NamedInstrProfRecord 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   EXPECT_THAT_ERROR(Writer.addRecord(std::move(Record11)), Succeeded());
647   // Merge profile data.
648   EXPECT_THAT_ERROR(Writer.addRecord(std::move(Record12)), Succeeded());
649 
650   auto Profile = Writer.writeBuffer();
651   readProfile(std::move(Profile));
652 
653   Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
654   EXPECT_THAT_ERROR(R.takeError(), Succeeded());
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 static void addValueProfData(InstrProfRecord &Record) {
666   Record.reserveSites(IPVK_IndirectCallTarget, 5);
667   InstrProfValueData VD0[] = {{uint64_t(callee1), 400},
668                               {uint64_t(callee2), 1000},
669                               {uint64_t(callee3), 500},
670                               {uint64_t(callee4), 300},
671                               {uint64_t(callee5), 100}};
672   Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 5, nullptr);
673   InstrProfValueData VD1[] = {{uint64_t(callee5), 800},
674                               {uint64_t(callee3), 1000},
675                               {uint64_t(callee2), 2500},
676                               {uint64_t(callee1), 1300}};
677   Record.addValueData(IPVK_IndirectCallTarget, 1, VD1, 4, nullptr);
678   InstrProfValueData VD2[] = {{uint64_t(callee6), 800},
679                               {uint64_t(callee3), 1000},
680                               {uint64_t(callee4), 5500}};
681   Record.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr);
682   InstrProfValueData VD3[] = {{uint64_t(callee2), 1800},
683                               {uint64_t(callee3), 2000}};
684   Record.addValueData(IPVK_IndirectCallTarget, 3, VD3, 2, nullptr);
685   Record.addValueData(IPVK_IndirectCallTarget, 4, nullptr, 0, nullptr);
686 }
687 
688 TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write) {
689   InstrProfRecord SrcRecord({1ULL << 31, 2});
690   addValueProfData(SrcRecord);
691   std::unique_ptr<ValueProfData> VPData =
692       ValueProfData::serializeFrom(SrcRecord);
693 
694   InstrProfRecord Record({1ULL << 31, 2});
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 
753 TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write_mapping) {
754 
755   NamedInstrProfRecord SrcRecord("caller", 0x1234, {1ULL << 31, 2});
756   addValueProfData(SrcRecord);
757   std::unique_ptr<ValueProfData> VPData =
758       ValueProfData::serializeFrom(SrcRecord);
759 
760   NamedInstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2});
761   InstrProfSymtab Symtab;
762   Symtab.mapAddress(uint64_t(callee1), 0x1000ULL);
763   Symtab.mapAddress(uint64_t(callee2), 0x2000ULL);
764   Symtab.mapAddress(uint64_t(callee3), 0x3000ULL);
765   Symtab.mapAddress(uint64_t(callee4), 0x4000ULL);
766   // Missing mapping for callee5
767   Symtab.finalizeSymtab();
768 
769   VPData->deserializeTo(Record, &Symtab.getAddrHashMap());
770 
771   // Now read data from Record and sanity check the data
772   ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget));
773   ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
774 
775   auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
776     return VD1.Count > VD2.Count;
777   };
778   std::unique_ptr<InstrProfValueData[]> VD_0(
779       Record.getValueForSite(IPVK_IndirectCallTarget, 0));
780   std::sort(&VD_0[0], &VD_0[5], Cmp);
781   ASSERT_EQ(VD_0[0].Value, 0x2000ULL);
782   ASSERT_EQ(1000U, VD_0[0].Count);
783   ASSERT_EQ(VD_0[1].Value, 0x3000ULL);
784   ASSERT_EQ(500U, VD_0[1].Count);
785   ASSERT_EQ(VD_0[2].Value, 0x1000ULL);
786   ASSERT_EQ(400U, VD_0[2].Count);
787 
788   // callee5 does not have a mapped value -- default to 0.
789   ASSERT_EQ(VD_0[4].Value, 0ULL);
790 }
791 
792 TEST_P(MaybeSparseInstrProfTest, get_max_function_count) {
793   EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1234, {1ULL << 31, 2}}),
794                     Succeeded());
795   EXPECT_THAT_ERROR(Writer.addRecord({"bar", 0, {1ULL << 63}}), Succeeded());
796   EXPECT_THAT_ERROR(Writer.addRecord({"baz", 0x5678, {0, 0, 0, 0}}),
797                     Succeeded());
798   auto Profile = Writer.writeBuffer();
799   readProfile(std::move(Profile));
800 
801   ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount());
802 }
803 
804 TEST_P(MaybeSparseInstrProfTest, get_weighted_function_counts) {
805   EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1234, {1, 2}}, 3), Succeeded());
806   EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1235, {3, 4}}, 5), Succeeded());
807   auto Profile = Writer.writeBuffer();
808   readProfile(std::move(Profile));
809 
810   std::vector<uint64_t> Counts;
811   EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1234, Counts),
812                     Succeeded());
813   ASSERT_EQ(2U, Counts.size());
814   ASSERT_EQ(3U, Counts[0]);
815   ASSERT_EQ(6U, Counts[1]);
816 
817   EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1235, Counts),
818                     Succeeded());
819   ASSERT_EQ(2U, Counts.size());
820   ASSERT_EQ(15U, Counts[0]);
821   ASSERT_EQ(20U, Counts[1]);
822 }
823 
824 // Testing symtab creator interface used by indexed profile reader.
825 TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_test) {
826   std::vector<StringRef> FuncNames;
827   FuncNames.push_back("func1");
828   FuncNames.push_back("func2");
829   FuncNames.push_back("func3");
830   FuncNames.push_back("bar1");
831   FuncNames.push_back("bar2");
832   FuncNames.push_back("bar3");
833   InstrProfSymtab Symtab;
834   EXPECT_THAT_ERROR(Symtab.create(FuncNames), Succeeded());
835   StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
836   ASSERT_EQ(StringRef("func1"), R);
837   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
838   ASSERT_EQ(StringRef("func2"), R);
839   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
840   ASSERT_EQ(StringRef("func3"), R);
841   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
842   ASSERT_EQ(StringRef("bar1"), R);
843   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
844   ASSERT_EQ(StringRef("bar2"), R);
845   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
846   ASSERT_EQ(StringRef("bar3"), R);
847 
848   // negative tests
849   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar4"));
850   ASSERT_EQ(StringRef(), R);
851   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("foo4"));
852   ASSERT_EQ(StringRef(), R);
853 
854   // Now incrementally update the symtab
855   EXPECT_THAT_ERROR(Symtab.addFuncName("blah_1"), Succeeded());
856   EXPECT_THAT_ERROR(Symtab.addFuncName("blah_2"), Succeeded());
857   EXPECT_THAT_ERROR(Symtab.addFuncName("blah_3"), Succeeded());
858   // Finalize it
859   Symtab.finalizeSymtab();
860 
861   // Check again
862   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_1"));
863   ASSERT_EQ(StringRef("blah_1"), R);
864   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_2"));
865   ASSERT_EQ(StringRef("blah_2"), R);
866   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_3"));
867   ASSERT_EQ(StringRef("blah_3"), R);
868   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
869   ASSERT_EQ(StringRef("func1"), R);
870   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
871   ASSERT_EQ(StringRef("func2"), R);
872   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
873   ASSERT_EQ(StringRef("func3"), R);
874   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
875   ASSERT_EQ(StringRef("bar1"), R);
876   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
877   ASSERT_EQ(StringRef("bar2"), R);
878   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
879   ASSERT_EQ(StringRef("bar3"), R);
880 }
881 
882 // Test that we get an error when creating a bogus symtab.
883 TEST_P(MaybeSparseInstrProfTest, instr_prof_bogus_symtab_empty_func_name) {
884   InstrProfSymtab Symtab;
885   EXPECT_TRUE(ErrorEquals(instrprof_error::malformed, Symtab.addFuncName("")));
886 }
887 
888 // Testing symtab creator interface used by value profile transformer.
889 TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_module_test) {
890   LLVMContext Ctx;
891   std::unique_ptr<Module> M = llvm::make_unique<Module>("MyModule.cpp", Ctx);
892   FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
893                                         /*isVarArg=*/false);
894   Function::Create(FTy, Function::ExternalLinkage, "Gfoo", M.get());
895   Function::Create(FTy, Function::ExternalLinkage, "Gblah", M.get());
896   Function::Create(FTy, Function::ExternalLinkage, "Gbar", M.get());
897   Function::Create(FTy, Function::InternalLinkage, "Ifoo", M.get());
898   Function::Create(FTy, Function::InternalLinkage, "Iblah", M.get());
899   Function::Create(FTy, Function::InternalLinkage, "Ibar", M.get());
900   Function::Create(FTy, Function::PrivateLinkage, "Pfoo", M.get());
901   Function::Create(FTy, Function::PrivateLinkage, "Pblah", M.get());
902   Function::Create(FTy, Function::PrivateLinkage, "Pbar", M.get());
903   Function::Create(FTy, Function::WeakODRLinkage, "Wfoo", M.get());
904   Function::Create(FTy, Function::WeakODRLinkage, "Wblah", M.get());
905   Function::Create(FTy, Function::WeakODRLinkage, "Wbar", M.get());
906 
907   InstrProfSymtab ProfSymtab;
908   EXPECT_THAT_ERROR(ProfSymtab.create(*M), Succeeded());
909 
910   StringRef Funcs[] = {"Gfoo", "Gblah", "Gbar", "Ifoo", "Iblah", "Ibar",
911                        "Pfoo", "Pblah", "Pbar", "Wfoo", "Wblah", "Wbar"};
912 
913   for (unsigned I = 0; I < sizeof(Funcs) / sizeof(*Funcs); I++) {
914     Function *F = M->getFunction(Funcs[I]);
915     ASSERT_TRUE(F != nullptr);
916     std::string PGOName = getPGOFuncName(*F);
917     uint64_t Key = IndexedInstrProf::ComputeHash(PGOName);
918     ASSERT_EQ(StringRef(PGOName),
919               ProfSymtab.getFuncName(Key));
920     ASSERT_EQ(StringRef(Funcs[I]), ProfSymtab.getOrigFuncName(Key));
921   }
922 }
923 
924 // Testing symtab serialization and creator/deserialization interface
925 // used by coverage map reader, and raw profile reader.
926 TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_compression_test) {
927   std::vector<std::string> FuncNames1;
928   std::vector<std::string> FuncNames2;
929   for (int I = 0; I < 3; I++) {
930     std::string str;
931     raw_string_ostream OS(str);
932     OS << "func_" << I;
933     FuncNames1.push_back(OS.str());
934     str.clear();
935     OS << "f oooooooooooooo_" << I;
936     FuncNames1.push_back(OS.str());
937     str.clear();
938     OS << "BAR_" << I;
939     FuncNames2.push_back(OS.str());
940     str.clear();
941     OS << "BlahblahBlahblahBar_" << I;
942     FuncNames2.push_back(OS.str());
943   }
944 
945   for (bool DoCompression : {false, true}) {
946     // Compressing:
947     std::string FuncNameStrings1;
948     EXPECT_THAT_ERROR(collectPGOFuncNameStrings(
949                           FuncNames1, (DoCompression && zlib::isAvailable()),
950                           FuncNameStrings1),
951                       Succeeded());
952 
953     // Compressing:
954     std::string FuncNameStrings2;
955     EXPECT_THAT_ERROR(collectPGOFuncNameStrings(
956                           FuncNames2, (DoCompression && zlib::isAvailable()),
957                           FuncNameStrings2),
958                       Succeeded());
959 
960     for (int Padding = 0; Padding < 2; Padding++) {
961       // Join with paddings :
962       std::string FuncNameStrings = FuncNameStrings1;
963       for (int P = 0; P < Padding; P++) {
964         FuncNameStrings.push_back('\0');
965       }
966       FuncNameStrings += FuncNameStrings2;
967 
968       // Now decompress:
969       InstrProfSymtab Symtab;
970       EXPECT_THAT_ERROR(Symtab.create(StringRef(FuncNameStrings)), Succeeded());
971 
972       // Now do the checks:
973       // First sampling some data points:
974       StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[0]));
975       ASSERT_EQ(StringRef("func_0"), R);
976       R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[1]));
977       ASSERT_EQ(StringRef("f oooooooooooooo_0"), R);
978       for (int I = 0; I < 3; I++) {
979         std::string N[4];
980         N[0] = FuncNames1[2 * I];
981         N[1] = FuncNames1[2 * I + 1];
982         N[2] = FuncNames2[2 * I];
983         N[3] = FuncNames2[2 * I + 1];
984         for (int J = 0; J < 4; J++) {
985           StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(N[J]));
986           ASSERT_EQ(StringRef(N[J]), R);
987         }
988       }
989     }
990   }
991 }
992 
993 TEST_F(SparseInstrProfTest, preserve_no_records) {
994   EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1234, {0}}), Succeeded());
995   EXPECT_THAT_ERROR(Writer.addRecord({"bar", 0x4321, {0, 0}}), Succeeded());
996   // FIXME: I'm guessing this data should be different, but the original author
997   // should check/update this test so it doesn't produce errors.
998   consumeError(Writer.addRecord({"bar", 0x4321, {0, 0, 0}}));
999 
1000   auto Profile = Writer.writeBuffer();
1001   readProfile(std::move(Profile));
1002 
1003   auto I = Reader->begin(), E = Reader->end();
1004   ASSERT_TRUE(I == E);
1005 }
1006 
1007 INSTANTIATE_TEST_CASE_P(MaybeSparse, MaybeSparseInstrProfTest,
1008                         ::testing::Bool(),);
1009 
1010 } // end anonymous namespace
1011