453ad0f22b3441b270df1fe051ad7c1ce217eed7
[oota-llvm.git] / unittests / ProfileData / InstrProfTest.cpp
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/ProfileData/InstrProfReader.h"
11 #include "llvm/ProfileData/InstrProfWriter.h"
12 #include "llvm/Support/Compression.h"
13 #include "gtest/gtest.h"
14
15 #include <cstdarg>
16
17 using namespace llvm;
18
19 static ::testing::AssertionResult NoError(std::error_code EC) {
20   if (!EC)
21     return ::testing::AssertionSuccess();
22   return ::testing::AssertionFailure() << "error " << EC.value()
23                                        << ": " << EC.message();
24 }
25
26 static ::testing::AssertionResult ErrorEquals(std::error_code Expected,
27                                               std::error_code Found) {
28   if (Expected == Found)
29     return ::testing::AssertionSuccess();
30   return ::testing::AssertionFailure() << "error " << Found.value()
31                                        << ": " << Found.message();
32 }
33
34 namespace {
35
36 struct InstrProfTest : ::testing::Test {
37   InstrProfWriter Writer;
38   std::unique_ptr<IndexedInstrProfReader> Reader;
39
40   void readProfile(std::unique_ptr<MemoryBuffer> Profile) {
41     auto ReaderOrErr = IndexedInstrProfReader::create(std::move(Profile));
42     ASSERT_TRUE(NoError(ReaderOrErr.getError()));
43     Reader = std::move(ReaderOrErr.get());
44   }
45 };
46
47 TEST_F(InstrProfTest, write_and_read_empty_profile) {
48   auto Profile = Writer.writeBuffer();
49   readProfile(std::move(Profile));
50   ASSERT_TRUE(Reader->begin() == Reader->end());
51 }
52
53 TEST_F(InstrProfTest, write_and_read_one_function) {
54   InstrProfRecord Record("foo", 0x1234, {1, 2, 3, 4});
55   Writer.addRecord(std::move(Record));
56   auto Profile = Writer.writeBuffer();
57   readProfile(std::move(Profile));
58
59   auto I = Reader->begin(), E = Reader->end();
60   ASSERT_TRUE(I != E);
61   ASSERT_EQ(StringRef("foo"), I->Name);
62   ASSERT_EQ(0x1234U, I->Hash);
63   ASSERT_EQ(4U, I->Counts.size());
64   ASSERT_EQ(1U, I->Counts[0]);
65   ASSERT_EQ(2U, I->Counts[1]);
66   ASSERT_EQ(3U, I->Counts[2]);
67   ASSERT_EQ(4U, I->Counts[3]);
68   ASSERT_TRUE(++I == E);
69 }
70
71 TEST_F(InstrProfTest, get_instr_prof_record) {
72   InstrProfRecord Record1("foo", 0x1234, {1, 2});
73   InstrProfRecord Record2("foo", 0x1235, {3, 4});
74   Writer.addRecord(std::move(Record1));
75   Writer.addRecord(std::move(Record2));
76   auto Profile = Writer.writeBuffer();
77   readProfile(std::move(Profile));
78
79   ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("foo", 0x1234);
80   ASSERT_TRUE(NoError(R.getError()));
81   ASSERT_EQ(2U, R.get().Counts.size());
82   ASSERT_EQ(1U, R.get().Counts[0]);
83   ASSERT_EQ(2U, R.get().Counts[1]);
84
85   R = Reader->getInstrProfRecord("foo", 0x1235);
86   ASSERT_TRUE(NoError(R.getError()));
87   ASSERT_EQ(2U, R.get().Counts.size());
88   ASSERT_EQ(3U, R.get().Counts[0]);
89   ASSERT_EQ(4U, R.get().Counts[1]);
90
91   R = Reader->getInstrProfRecord("foo", 0x5678);
92   ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, R.getError()));
93
94   R = Reader->getInstrProfRecord("bar", 0x1234);
95   ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, R.getError()));
96 }
97
98 TEST_F(InstrProfTest, get_function_counts) {
99   InstrProfRecord Record1("foo", 0x1234, {1, 2});
100   InstrProfRecord Record2("foo", 0x1235, {3, 4});
101   Writer.addRecord(std::move(Record1));
102   Writer.addRecord(std::move(Record2));
103   auto Profile = Writer.writeBuffer();
104   readProfile(std::move(Profile));
105
106   std::vector<uint64_t> Counts;
107   ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1234, Counts)));
108   ASSERT_EQ(2U, Counts.size());
109   ASSERT_EQ(1U, Counts[0]);
110   ASSERT_EQ(2U, Counts[1]);
111
112   ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1235, Counts)));
113   ASSERT_EQ(2U, Counts.size());
114   ASSERT_EQ(3U, Counts[0]);
115   ASSERT_EQ(4U, Counts[1]);
116
117   std::error_code EC;
118   EC = Reader->getFunctionCounts("foo", 0x5678, Counts);
119   ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, EC));
120
121   EC = Reader->getFunctionCounts("bar", 0x1234, Counts);
122   ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, EC));
123 }
124
125 TEST_F(InstrProfTest, get_icall_data_read_write) {
126   InstrProfRecord Record1("caller", 0x1234, {1, 2});
127   InstrProfRecord Record2("callee1", 0x1235, {3, 4});
128   InstrProfRecord Record3("callee2", 0x1235, {3, 4});
129   InstrProfRecord Record4("callee3", 0x1235, {3, 4});
130
131   // 4 value sites.
132   Record1.reserveSites(IPVK_IndirectCallTarget, 4);
133   InstrProfValueData VD0[] = {{(uint64_t) "callee1", 1},
134                               {(uint64_t) "callee2", 2},
135                               {(uint64_t) "callee3", 3}};
136   Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
137   // No value profile data at the second site.
138   Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
139   InstrProfValueData VD2[] = {{(uint64_t) "callee1", 1},
140                               {(uint64_t) "callee2", 2}};
141   Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
142   InstrProfValueData VD3[] = {{(uint64_t) "callee1", 1}};
143   Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
144
145   Writer.addRecord(std::move(Record1));
146   Writer.addRecord(std::move(Record2));
147   Writer.addRecord(std::move(Record3));
148   Writer.addRecord(std::move(Record4));
149   auto Profile = Writer.writeBuffer();
150   readProfile(std::move(Profile));
151
152   ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
153   ASSERT_TRUE(NoError(R.getError()));
154   ASSERT_EQ(4U, R.get().getNumValueSites(IPVK_IndirectCallTarget));
155   ASSERT_EQ(3U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
156   ASSERT_EQ(0U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
157   ASSERT_EQ(2U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
158   ASSERT_EQ(1U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
159
160   std::unique_ptr<InstrProfValueData[]> VD =
161       R.get().getValueForSite(IPVK_IndirectCallTarget, 0);
162   // Now sort the target acording to frequency.
163   std::sort(&VD[0], &VD[3],
164             [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
165               return VD1.Count > VD2.Count;
166             });
167   ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
168   ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
169   ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
170 }
171
172 TEST_F(InstrProfTest, get_icall_data_read_write_big_endian) {
173   InstrProfRecord Record1("caller", 0x1234, {1, 2});
174   InstrProfRecord Record2("callee1", 0x1235, {3, 4});
175   InstrProfRecord Record3("callee2", 0x1235, {3, 4});
176   InstrProfRecord Record4("callee3", 0x1235, {3, 4});
177
178   // 4 value sites.
179   Record1.reserveSites(IPVK_IndirectCallTarget, 4);
180   InstrProfValueData VD0[] = {{(uint64_t) "callee1", 1},
181                               {(uint64_t) "callee2", 2},
182                               {(uint64_t) "callee3", 3}};
183   Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
184   // No value profile data at the second site.
185   Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
186   InstrProfValueData VD2[] = {{(uint64_t) "callee1", 1},
187                               {(uint64_t) "callee2", 2}};
188   Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
189   InstrProfValueData VD3[] = {{(uint64_t) "callee1", 1}};
190   Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
191
192   Writer.addRecord(std::move(Record1));
193   Writer.addRecord(std::move(Record2));
194   Writer.addRecord(std::move(Record3));
195   Writer.addRecord(std::move(Record4));
196
197   // Set big endian output.
198   Writer.setValueProfDataEndianness(support::big);
199
200   auto Profile = Writer.writeBuffer();
201   readProfile(std::move(Profile));
202
203   // Set big endian input.
204   Reader->setValueProfDataEndianness(support::big);
205
206   ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
207   ASSERT_TRUE(NoError(R.getError()));
208   ASSERT_EQ(4U, R.get().getNumValueSites(IPVK_IndirectCallTarget));
209   ASSERT_EQ(3U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
210   ASSERT_EQ(0U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
211   ASSERT_EQ(2U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
212   ASSERT_EQ(1U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
213
214   std::unique_ptr<InstrProfValueData[]> VD =
215       R.get().getValueForSite(IPVK_IndirectCallTarget, 0);
216   // Now sort the target acording to frequency.
217   std::sort(&VD[0], &VD[3],
218             [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
219               return VD1.Count > VD2.Count;
220             });
221   ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
222   ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
223   ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
224
225   // Restore little endian default:
226   Writer.setValueProfDataEndianness(support::little);
227 }
228
229 TEST_F(InstrProfTest, get_icall_data_merge1) {
230   static const char caller[] = "caller";
231   static const char callee1[] = "callee1";
232   static const char callee2[] = "callee2";
233   static const char callee3[] = "callee3";
234   static const char callee4[] = "callee4";
235
236   InstrProfRecord Record11(caller, 0x1234, {1, 2});
237   InstrProfRecord Record12(caller, 0x1234, {1, 2});
238   InstrProfRecord Record2(callee1, 0x1235, {3, 4});
239   InstrProfRecord Record3(callee2, 0x1235, {3, 4});
240   InstrProfRecord Record4(callee3, 0x1235, {3, 4});
241   InstrProfRecord Record5(callee3, 0x1235, {3, 4});
242   InstrProfRecord Record6(callee4, 0x1235, {3, 5});
243
244   // 5 value sites.
245   Record11.reserveSites(IPVK_IndirectCallTarget, 5);
246   InstrProfValueData VD0[] = {{uint64_t(callee1), 1},
247                               {uint64_t(callee2), 2},
248                               {uint64_t(callee3), 3},
249                               {uint64_t(callee4), 4}};
250   Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 4, nullptr);
251
252   // No valeu profile data at the second site.
253   Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
254
255   InstrProfValueData VD2[] = {{uint64_t(callee1), 1},
256                               {uint64_t(callee2), 2},
257                               {uint64_t(callee3), 3}};
258   Record11.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr);
259
260   InstrProfValueData VD3[] = {{uint64_t(callee1), 1}};
261   Record11.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
262
263   InstrProfValueData VD4[] = {{uint64_t(callee1), 1},
264                               {uint64_t(callee2), 2},
265                               {uint64_t(callee3), 3}};
266   Record11.addValueData(IPVK_IndirectCallTarget, 4, VD4, 3, nullptr);
267
268   // A differnt record for the same caller.
269   Record12.reserveSites(IPVK_IndirectCallTarget, 5);
270   InstrProfValueData VD02[] = {{uint64_t(callee2), 5},
271                                {uint64_t(callee3), 3}};
272   Record12.addValueData(IPVK_IndirectCallTarget, 0, VD02, 2, nullptr);
273
274   // No valeu profile data at the second site.
275   Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
276
277   InstrProfValueData VD22[] = {{uint64_t(callee2), 1},
278                                {uint64_t(callee3), 3},
279                                {uint64_t(callee4), 4}};
280   Record12.addValueData(IPVK_IndirectCallTarget, 2, VD22, 3, nullptr);
281
282   Record12.addValueData(IPVK_IndirectCallTarget, 3, nullptr, 0, nullptr);
283
284   InstrProfValueData VD42[] = {{uint64_t(callee1), 1},
285                                {uint64_t(callee2), 2},
286                                {uint64_t(callee3), 3}};
287   Record12.addValueData(IPVK_IndirectCallTarget, 4, VD42, 3, nullptr);
288
289   Writer.addRecord(std::move(Record11));
290   // Merge profile data.
291   Writer.addRecord(std::move(Record12));
292
293   Writer.addRecord(std::move(Record2));
294   Writer.addRecord(std::move(Record3));
295   Writer.addRecord(std::move(Record4));
296   Writer.addRecord(std::move(Record5));
297   Writer.addRecord(std::move(Record6));
298   auto Profile = Writer.writeBuffer();
299   readProfile(std::move(Profile));
300
301   ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
302   ASSERT_TRUE(NoError(R.getError()));
303   ASSERT_EQ(5U, R.get().getNumValueSites(IPVK_IndirectCallTarget));
304   ASSERT_EQ(4U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
305   ASSERT_EQ(0U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
306   ASSERT_EQ(4U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
307   ASSERT_EQ(1U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
308   ASSERT_EQ(3U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 4));
309
310   std::unique_ptr<InstrProfValueData[]> VD =
311       R.get().getValueForSite(IPVK_IndirectCallTarget, 0);
312   // Now sort the target acording to frequency.
313   std::sort(&VD[0], &VD[4],
314             [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
315               return VD1.Count > VD2.Count;
316             });
317   ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee2"));
318   ASSERT_EQ(7U, VD[0].Count);
319   ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee3"));
320   ASSERT_EQ(6U, VD[1].Count);
321   ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee4"));
322   ASSERT_EQ(4U, VD[2].Count);
323   ASSERT_EQ(StringRef((const char *)VD[3].Value, 7), StringRef("callee1"));
324   ASSERT_EQ(1U, VD[3].Count);
325
326   std::unique_ptr<InstrProfValueData[]> VD_2(
327       R.get().getValueForSite(IPVK_IndirectCallTarget, 2));
328   std::sort(&VD_2[0], &VD_2[4],
329             [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
330               return VD1.Count > VD2.Count;
331             });
332   ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee3"));
333   ASSERT_EQ(6U, VD_2[0].Count);
334   ASSERT_EQ(StringRef((const char *)VD_2[1].Value, 7), StringRef("callee4"));
335   ASSERT_EQ(4U, VD_2[1].Count);
336   ASSERT_EQ(StringRef((const char *)VD_2[2].Value, 7), StringRef("callee2"));
337   ASSERT_EQ(3U, VD_2[2].Count);
338   ASSERT_EQ(StringRef((const char *)VD_2[3].Value, 7), StringRef("callee1"));
339   ASSERT_EQ(1U, VD_2[3].Count);
340
341   std::unique_ptr<InstrProfValueData[]> VD_3(
342       R.get().getValueForSite(IPVK_IndirectCallTarget, 3));
343   ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee1"));
344   ASSERT_EQ(1U, VD_3[0].Count);
345
346   std::unique_ptr<InstrProfValueData[]> VD_4(
347       R.get().getValueForSite(IPVK_IndirectCallTarget, 4));
348   std::sort(&VD_4[0], &VD_4[3],
349             [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
350               return VD1.Count > VD2.Count;
351             });
352   ASSERT_EQ(StringRef((const char *)VD_4[0].Value, 7), StringRef("callee3"));
353   ASSERT_EQ(6U, VD_4[0].Count);
354   ASSERT_EQ(StringRef((const char *)VD_4[1].Value, 7), StringRef("callee2"));
355   ASSERT_EQ(4U, VD_4[1].Count);
356   ASSERT_EQ(StringRef((const char *)VD_4[2].Value, 7), StringRef("callee1"));
357   ASSERT_EQ(2U, VD_4[2].Count);
358 }
359
360 TEST_F(InstrProfTest, get_icall_data_merge1_saturation) {
361   static const char bar[] = "bar";
362
363   const uint64_t Max = std::numeric_limits<uint64_t>::max();
364
365   InstrProfRecord Record1("foo", 0x1234, {1});
366   auto Result1 = Writer.addRecord(std::move(Record1));
367   ASSERT_EQ(Result1, instrprof_error::success);
368
369   // Verify counter overflow.
370   InstrProfRecord Record2("foo", 0x1234, {Max});
371   auto Result2 = Writer.addRecord(std::move(Record2));
372   ASSERT_EQ(Result2, instrprof_error::counter_overflow);
373
374   InstrProfRecord Record3(bar, 0x9012, {8});
375   auto Result3 = Writer.addRecord(std::move(Record3));
376   ASSERT_EQ(Result3, instrprof_error::success);
377
378   InstrProfRecord Record4("baz", 0x5678, {3, 4});
379   Record4.reserveSites(IPVK_IndirectCallTarget, 1);
380   InstrProfValueData VD4[] = {{uint64_t(bar), 1}};
381   Record4.addValueData(IPVK_IndirectCallTarget, 0, VD4, 1, nullptr);
382   auto Result4 = Writer.addRecord(std::move(Record4));
383   ASSERT_EQ(Result4, instrprof_error::success);
384
385   // Verify value data counter overflow.
386   InstrProfRecord Record5("baz", 0x5678, {5, 6});
387   Record5.reserveSites(IPVK_IndirectCallTarget, 1);
388   InstrProfValueData VD5[] = {{uint64_t(bar), Max}};
389   Record5.addValueData(IPVK_IndirectCallTarget, 0, VD5, 1, nullptr);
390   auto Result5 = Writer.addRecord(std::move(Record5));
391   ASSERT_EQ(Result5, instrprof_error::counter_overflow);
392
393   auto Profile = Writer.writeBuffer();
394   readProfile(std::move(Profile));
395
396   // Verify saturation of counts.
397   ErrorOr<InstrProfRecord> ReadRecord1 =
398       Reader->getInstrProfRecord("foo", 0x1234);
399   ASSERT_TRUE(NoError(ReadRecord1.getError()));
400   ASSERT_EQ(Max, ReadRecord1.get().Counts[0]);
401
402   ErrorOr<InstrProfRecord> ReadRecord2 =
403       Reader->getInstrProfRecord("baz", 0x5678);
404   ASSERT_EQ(1U, ReadRecord2.get().getNumValueSites(IPVK_IndirectCallTarget));
405   std::unique_ptr<InstrProfValueData[]> VD =
406       ReadRecord2.get().getValueForSite(IPVK_IndirectCallTarget, 0);
407   ASSERT_EQ(StringRef("bar"), StringRef((const char *)VD[0].Value, 3));
408   ASSERT_EQ(Max, VD[0].Count);
409 }
410
411 // Synthesize runtime value profile data.
412 ValueProfNode Site1Values[5] = {{{uint64_t("callee1"), 400}, &Site1Values[1]},
413                                 {{uint64_t("callee2"), 1000}, &Site1Values[2]},
414                                 {{uint64_t("callee3"), 500}, &Site1Values[3]},
415                                 {{uint64_t("callee4"), 300}, &Site1Values[4]},
416                                 {{uint64_t("callee5"), 100}, 0}};
417
418 ValueProfNode Site2Values[4] = {{{uint64_t("callee5"), 800}, &Site2Values[1]},
419                                 {{uint64_t("callee3"), 1000}, &Site2Values[2]},
420                                 {{uint64_t("callee2"), 2500}, &Site2Values[3]},
421                                 {{uint64_t("callee1"), 1300}, 0}};
422
423 ValueProfNode Site3Values[3] = {{{uint64_t("callee6"), 800}, &Site3Values[1]},
424                                 {{uint64_t("callee3"), 1000}, &Site3Values[2]},
425                                 {{uint64_t("callee4"), 5500}, 0}};
426
427 ValueProfNode Site4Values[2] = {{{uint64_t("callee2"), 1800}, &Site4Values[1]},
428                                 {{uint64_t("callee3"), 2000}, 0}};
429
430 static ValueProfNode *ValueProfNodes[5] = {&Site1Values[0], &Site2Values[0],
431                                            &Site3Values[0], &Site4Values[0], 0};
432 static uint16_t NumValueSites[IPVK_Last + 1] = {5};
433 TEST_F(InstrProfTest, runtime_value_prof_data_read_write) {
434   ValueProfRuntimeRecord RTRecord;
435   initializeValueProfRuntimeRecord(&RTRecord, &NumValueSites[0],
436                                    &ValueProfNodes[0]);
437
438   ValueProfData *VPData = serializeValueProfDataFromRT(&RTRecord, nullptr);
439
440   InstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2});
441
442   VPData->deserializeTo(Record, 0);
443
444   // Now read data from Record and sanity check the data
445   ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget));
446   ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
447   ASSERT_EQ(4U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
448   ASSERT_EQ(3U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
449   ASSERT_EQ(2U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
450   ASSERT_EQ(0U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 4));
451
452   auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
453     return VD1.Count > VD2.Count;
454   };
455   std::unique_ptr<InstrProfValueData[]> VD_0(
456       Record.getValueForSite(IPVK_IndirectCallTarget, 0));
457   std::sort(&VD_0[0], &VD_0[5], Cmp);
458   ASSERT_EQ(StringRef((const char *)VD_0[0].Value, 7), StringRef("callee2"));
459   ASSERT_EQ(1000U, VD_0[0].Count);
460   ASSERT_EQ(StringRef((const char *)VD_0[1].Value, 7), StringRef("callee3"));
461   ASSERT_EQ(500U, VD_0[1].Count);
462   ASSERT_EQ(StringRef((const char *)VD_0[2].Value, 7), StringRef("callee1"));
463   ASSERT_EQ(400U, VD_0[2].Count);
464   ASSERT_EQ(StringRef((const char *)VD_0[3].Value, 7), StringRef("callee4"));
465   ASSERT_EQ(300U, VD_0[3].Count);
466   ASSERT_EQ(StringRef((const char *)VD_0[4].Value, 7), StringRef("callee5"));
467   ASSERT_EQ(100U, VD_0[4].Count);
468
469   std::unique_ptr<InstrProfValueData[]> VD_1(
470       Record.getValueForSite(IPVK_IndirectCallTarget, 1));
471   std::sort(&VD_1[0], &VD_1[4], Cmp);
472   ASSERT_EQ(StringRef((const char *)VD_1[0].Value, 7), StringRef("callee2"));
473   ASSERT_EQ(2500U, VD_1[0].Count);
474   ASSERT_EQ(StringRef((const char *)VD_1[1].Value, 7), StringRef("callee1"));
475   ASSERT_EQ(1300U, VD_1[1].Count);
476   ASSERT_EQ(StringRef((const char *)VD_1[2].Value, 7), StringRef("callee3"));
477   ASSERT_EQ(1000U, VD_1[2].Count);
478   ASSERT_EQ(StringRef((const char *)VD_1[3].Value, 7), StringRef("callee5"));
479   ASSERT_EQ(800U, VD_1[3].Count);
480
481   std::unique_ptr<InstrProfValueData[]> VD_2(
482       Record.getValueForSite(IPVK_IndirectCallTarget, 2));
483   std::sort(&VD_2[0], &VD_2[3], Cmp);
484   ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee4"));
485   ASSERT_EQ(5500U, VD_2[0].Count);
486   ASSERT_EQ(StringRef((const char *)VD_2[1].Value, 7), StringRef("callee3"));
487   ASSERT_EQ(1000U, VD_2[1].Count);
488   ASSERT_EQ(StringRef((const char *)VD_2[2].Value, 7), StringRef("callee6"));
489   ASSERT_EQ(800U, VD_2[2].Count);
490
491   std::unique_ptr<InstrProfValueData[]> VD_3(
492       Record.getValueForSite(IPVK_IndirectCallTarget, 3));
493   std::sort(&VD_3[0], &VD_3[2], Cmp);
494   ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee3"));
495   ASSERT_EQ(2000U, VD_3[0].Count);
496   ASSERT_EQ(StringRef((const char *)VD_3[1].Value, 7), StringRef("callee2"));
497   ASSERT_EQ(1800U, VD_3[1].Count);
498
499   finalizeValueProfRuntimeRecord(&RTRecord);
500   free(VPData);
501 }
502
503 TEST_F(InstrProfTest, get_max_function_count) {
504   InstrProfRecord Record1("foo", 0x1234, {1ULL << 31, 2});
505   InstrProfRecord Record2("bar", 0, {1ULL << 63});
506   InstrProfRecord Record3("baz", 0x5678, {0, 0, 0, 0});
507   Writer.addRecord(std::move(Record1));
508   Writer.addRecord(std::move(Record2));
509   Writer.addRecord(std::move(Record3));
510   auto Profile = Writer.writeBuffer();
511   readProfile(std::move(Profile));
512
513   ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount());
514 }
515
516 TEST_F(InstrProfTest, get_weighted_function_counts) {
517   InstrProfRecord Record1("foo", 0x1234, {1, 2});
518   InstrProfRecord Record2("foo", 0x1235, {3, 4});
519   Writer.addRecord(std::move(Record1), 3);
520   Writer.addRecord(std::move(Record2), 5);
521   auto Profile = Writer.writeBuffer();
522   readProfile(std::move(Profile));
523
524   std::vector<uint64_t> Counts;
525   ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1234, Counts)));
526   ASSERT_EQ(2U, Counts.size());
527   ASSERT_EQ(3U, Counts[0]);
528   ASSERT_EQ(6U, Counts[1]);
529
530   ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1235, Counts)));
531   ASSERT_EQ(2U, Counts.size());
532   ASSERT_EQ(15U, Counts[0]);
533   ASSERT_EQ(20U, Counts[1]);
534 }
535
536 TEST_F(InstrProfTest, instr_prof_symtab_test) {
537   std::vector<StringRef> FuncNames;
538   FuncNames.push_back("func1");
539   FuncNames.push_back("func2");
540   FuncNames.push_back("func3");
541   FuncNames.push_back("bar1");
542   FuncNames.push_back("bar2");
543   FuncNames.push_back("bar3");
544   InstrProfSymtab Symtab;
545   Symtab.create(FuncNames);
546   StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
547   ASSERT_EQ(StringRef("func1"), R);
548   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
549   ASSERT_EQ(StringRef("func2"), R);
550   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
551   ASSERT_EQ(StringRef("func3"), R);
552   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
553   ASSERT_EQ(StringRef("bar1"), R);
554   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
555   ASSERT_EQ(StringRef("bar2"), R);
556   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
557   ASSERT_EQ(StringRef("bar3"), R);
558
559   // Now incrementally update the symtab
560   Symtab.addFuncName("blah_1");
561   Symtab.addFuncName("blah_2");
562   Symtab.addFuncName("blah_3");
563   // Finalize it
564   Symtab.finalizeSymtab();
565
566   // Check again
567   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_1"));
568   ASSERT_EQ(StringRef("blah_1"), R);
569   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_2"));
570   ASSERT_EQ(StringRef("blah_2"), R);
571   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_3"));
572   ASSERT_EQ(StringRef("blah_3"), R);
573   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
574   ASSERT_EQ(StringRef("func1"), R);
575   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
576   ASSERT_EQ(StringRef("func2"), R);
577   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
578   ASSERT_EQ(StringRef("func3"), R);
579   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
580   ASSERT_EQ(StringRef("bar1"), R);
581   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
582   ASSERT_EQ(StringRef("bar2"), R);
583   R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
584   ASSERT_EQ(StringRef("bar3"), R);
585 }
586
587 TEST_F(InstrProfTest, instr_prof_symtab_compression_test) {
588   std::vector<std::string> FuncNames1;
589   std::vector<std::string> FuncNames2;
590   for (int I = 0; I < 10 * 1024; I++) {
591     std::string str;
592     raw_string_ostream OS(str);
593     OS << "func_" << I;
594     FuncNames1.push_back(OS.str());
595     str.clear();
596     OS << "fooooooooooooooo_" << I;
597     FuncNames1.push_back(OS.str());
598     str.clear();
599     OS << "BAR_" << I;
600     FuncNames2.push_back(OS.str());
601     str.clear();
602     OS << "BlahblahBlahblahBar_" << I;
603     FuncNames2.push_back(OS.str());
604   }
605
606   for (int Padding = 0; Padding < 10; Padding++) {
607     for (int DoCompression = 0; DoCompression < 2; DoCompression++) {
608       // Compressing:
609       std::string FuncNameStrings1;
610       collectPGOFuncNameStrings(FuncNames1,
611                                 (DoCompression != 0 && zlib::isAvailable()),
612                                 FuncNameStrings1);
613
614       // Compressing:
615       std::string FuncNameStrings2;
616       collectPGOFuncNameStrings(FuncNames2,
617                                 (DoCompression != 0 && zlib::isAvailable()),
618                                 FuncNameStrings2);
619
620       // Join with paddings:
621       std::string FuncNameStrings = FuncNameStrings1;
622       for (int P = 0; P < Padding; P++) {
623         FuncNameStrings.push_back('\0');
624       }
625       FuncNameStrings += FuncNameStrings2;
626
627       // Now decompress
628       InstrProfSymtab Symtab;
629       Symtab.create(StringRef(FuncNameStrings));
630
631       // Now check
632       for (int I = 0; I < 10 * 1024; I++) {
633         std::string N[4];
634         N[0] = FuncNames1[2 * I];
635         N[1] = FuncNames1[2 * I + 1];
636         N[2] = FuncNames2[2 * I];
637         N[3] = FuncNames2[2 * I + 1];
638         for (int J = 0; J < 4; J++) {
639           StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(N[J]));
640           ASSERT_EQ(StringRef(N[J]), R);
641         }
642       }
643     }
644   }
645 }
646
647 } // end anonymous namespace