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