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