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