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