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