blob: 1b44463cd65043d2ef96794bd6a40b80aae174fe [file] [log] [blame]
Eugene Zelenkoffec81c2015-11-04 22:32:32 +00001//===- unittest/ProfileData/InstrProfTest.cpp -------------------*- C++ -*-===//
Justin Bogner2b6c5372015-02-18 01:58:17 +00002//
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
Xinliang David Li59411db2016-01-20 01:26:34 +000010#include "llvm/IR/Function.h"
Xinliang David Li402477d2016-02-04 19:11:43 +000011#include "llvm/IR/IRBuilder.h"
Xinliang David Li59411db2016-01-20 01:26:34 +000012#include "llvm/IR/LLVMContext.h"
13#include "llvm/IR/Module.h"
Justin Bogner2b6c5372015-02-18 01:58:17 +000014#include "llvm/ProfileData/InstrProfReader.h"
15#include "llvm/ProfileData/InstrProfWriter.h"
Xinliang David Lie413f1a2015-12-31 07:57:16 +000016#include "llvm/Support/Compression.h"
Justin Bogner2b6c5372015-02-18 01:58:17 +000017#include "gtest/gtest.h"
Justin Bogner2b6c5372015-02-18 01:58:17 +000018#include <cstdarg>
19
20using namespace llvm;
21
Vedant Kumar9152fd12016-05-19 03:54:45 +000022static ::testing::AssertionResult NoError(Error E) {
23 if (!E)
Justin Bogner2b6c5372015-02-18 01:58:17 +000024 return ::testing::AssertionSuccess();
Vedant Kumar9152fd12016-05-19 03:54:45 +000025 return ::testing::AssertionFailure() << "error: " << toString(std::move(E))
26 << "\n";
Justin Bogner2b6c5372015-02-18 01:58:17 +000027}
28
Vedant Kumar9152fd12016-05-19 03:54:45 +000029static ::testing::AssertionResult ErrorEquals(instrprof_error Expected,
30 Error E) {
31 instrprof_error Found;
32 std::string FoundMsg;
33 handleAllErrors(std::move(E), [&](const InstrProfError &IPE) {
34 Found = IPE.get();
35 FoundMsg = IPE.message();
36 });
Justin Bogner2b6c5372015-02-18 01:58:17 +000037 if (Expected == Found)
38 return ::testing::AssertionSuccess();
Vedant Kumar9152fd12016-05-19 03:54:45 +000039 return ::testing::AssertionFailure() << "error: " << FoundMsg << "\n";
Justin Bogner2b6c5372015-02-18 01:58:17 +000040}
41
42namespace {
43
44struct InstrProfTest : ::testing::Test {
45 InstrProfWriter Writer;
46 std::unique_ptr<IndexedInstrProfReader> Reader;
47
Vedant Kumar00dab222016-01-29 22:54:45 +000048 void SetUp() { Writer.setOutputSparse(false); }
49
Justin Bogner2b6c5372015-02-18 01:58:17 +000050 void readProfile(std::unique_ptr<MemoryBuffer> Profile) {
51 auto ReaderOrErr = IndexedInstrProfReader::create(std::move(Profile));
Vedant Kumar9152fd12016-05-19 03:54:45 +000052 ASSERT_TRUE(NoError(ReaderOrErr.takeError()));
Justin Bogner2b6c5372015-02-18 01:58:17 +000053 Reader = std::move(ReaderOrErr.get());
54 }
55};
56
Vedant Kumar00dab222016-01-29 22:54:45 +000057struct SparseInstrProfTest : public InstrProfTest {
58 void SetUp() { Writer.setOutputSparse(true); }
59};
60
61struct MaybeSparseInstrProfTest : public InstrProfTest,
62 public ::testing::WithParamInterface<bool> {
Vedant Kumar0259b7b2016-03-22 15:14:18 +000063 void SetUp() { Writer.setOutputSparse(GetParam()); }
Vedant Kumar00dab222016-01-29 22:54:45 +000064};
65
66TEST_P(MaybeSparseInstrProfTest, write_and_read_empty_profile) {
Justin Bogner2b6c5372015-02-18 01:58:17 +000067 auto Profile = Writer.writeBuffer();
68 readProfile(std::move(Profile));
69 ASSERT_TRUE(Reader->begin() == Reader->end());
70}
71
Vedant Kumar00dab222016-01-29 22:54:45 +000072TEST_P(MaybeSparseInstrProfTest, write_and_read_one_function) {
Justin Bogner9e9a0572015-09-29 22:13:58 +000073 InstrProfRecord Record("foo", 0x1234, {1, 2, 3, 4});
Vedant Kumarec210812016-05-03 17:07:06 +000074 NoError(Writer.addRecord(std::move(Record)));
Justin Bogner2b6c5372015-02-18 01:58:17 +000075 auto Profile = Writer.writeBuffer();
76 readProfile(std::move(Profile));
77
78 auto I = Reader->begin(), E = Reader->end();
79 ASSERT_TRUE(I != E);
80 ASSERT_EQ(StringRef("foo"), I->Name);
81 ASSERT_EQ(0x1234U, I->Hash);
82 ASSERT_EQ(4U, I->Counts.size());
83 ASSERT_EQ(1U, I->Counts[0]);
84 ASSERT_EQ(2U, I->Counts[1]);
85 ASSERT_EQ(3U, I->Counts[2]);
86 ASSERT_EQ(4U, I->Counts[3]);
87 ASSERT_TRUE(++I == E);
88}
89
Vedant Kumar00dab222016-01-29 22:54:45 +000090TEST_P(MaybeSparseInstrProfTest, get_instr_prof_record) {
Xinliang David Li2004f002015-11-02 05:08:23 +000091 InstrProfRecord Record1("foo", 0x1234, {1, 2});
92 InstrProfRecord Record2("foo", 0x1235, {3, 4});
Vedant Kumarec210812016-05-03 17:07:06 +000093 NoError(Writer.addRecord(std::move(Record1)));
94 NoError(Writer.addRecord(std::move(Record2)));
Xinliang David Li2004f002015-11-02 05:08:23 +000095 auto Profile = Writer.writeBuffer();
96 readProfile(std::move(Profile));
97
Vedant Kumar9152fd12016-05-19 03:54:45 +000098 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("foo", 0x1234);
99 ASSERT_TRUE(NoError(R.takeError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000100 ASSERT_EQ(2U, R->Counts.size());
101 ASSERT_EQ(1U, R->Counts[0]);
102 ASSERT_EQ(2U, R->Counts[1]);
Xinliang David Li2004f002015-11-02 05:08:23 +0000103
104 R = Reader->getInstrProfRecord("foo", 0x1235);
Vedant Kumar9152fd12016-05-19 03:54:45 +0000105 ASSERT_TRUE(NoError(R.takeError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000106 ASSERT_EQ(2U, R->Counts.size());
107 ASSERT_EQ(3U, R->Counts[0]);
108 ASSERT_EQ(4U, R->Counts[1]);
Xinliang David Li2004f002015-11-02 05:08:23 +0000109
110 R = Reader->getInstrProfRecord("foo", 0x5678);
Vedant Kumar9152fd12016-05-19 03:54:45 +0000111 ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, R.takeError()));
Xinliang David Li2004f002015-11-02 05:08:23 +0000112
113 R = Reader->getInstrProfRecord("bar", 0x1234);
Vedant Kumar9152fd12016-05-19 03:54:45 +0000114 ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, R.takeError()));
Xinliang David Li2004f002015-11-02 05:08:23 +0000115}
116
Vedant Kumar00dab222016-01-29 22:54:45 +0000117TEST_P(MaybeSparseInstrProfTest, get_function_counts) {
Justin Bogner9e9a0572015-09-29 22:13:58 +0000118 InstrProfRecord Record1("foo", 0x1234, {1, 2});
119 InstrProfRecord Record2("foo", 0x1235, {3, 4});
Vedant Kumarec210812016-05-03 17:07:06 +0000120 NoError(Writer.addRecord(std::move(Record1)));
121 NoError(Writer.addRecord(std::move(Record2)));
Justin Bogner2b6c5372015-02-18 01:58:17 +0000122 auto Profile = Writer.writeBuffer();
123 readProfile(std::move(Profile));
124
125 std::vector<uint64_t> Counts;
126 ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1234, Counts)));
127 ASSERT_EQ(2U, Counts.size());
128 ASSERT_EQ(1U, Counts[0]);
129 ASSERT_EQ(2U, Counts[1]);
130
Justin Bogner09829f42015-06-22 23:56:53 +0000131 ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1235, Counts)));
132 ASSERT_EQ(2U, Counts.size());
133 ASSERT_EQ(3U, Counts[0]);
134 ASSERT_EQ(4U, Counts[1]);
135
Vedant Kumar9152fd12016-05-19 03:54:45 +0000136 Error E1 = Reader->getFunctionCounts("foo", 0x5678, Counts);
137 ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, std::move(E1)));
Justin Bogner2b6c5372015-02-18 01:58:17 +0000138
Vedant Kumar9152fd12016-05-19 03:54:45 +0000139 Error E2 = Reader->getFunctionCounts("bar", 0x1234, Counts);
140 ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, std::move(E2)));
Justin Bogner2b6c5372015-02-18 01:58:17 +0000141}
142
Xinliang David Li6c93ee82016-02-03 04:08:18 +0000143// Profile data is copied from general.proftext
144TEST_F(InstrProfTest, get_profile_summary) {
145 InstrProfRecord Record1("func1", 0x1234, {97531});
146 InstrProfRecord Record2("func2", 0x1234, {0, 0});
147 InstrProfRecord Record3("func3", 0x1234,
148 {2305843009213693952, 1152921504606846976,
149 576460752303423488, 288230376151711744,
150 144115188075855872, 72057594037927936});
151 InstrProfRecord Record4("func4", 0x1234, {0});
Vedant Kumarec210812016-05-03 17:07:06 +0000152 NoError(Writer.addRecord(std::move(Record1)));
153 NoError(Writer.addRecord(std::move(Record2)));
154 NoError(Writer.addRecord(std::move(Record3)));
155 NoError(Writer.addRecord(std::move(Record4)));
Xinliang David Li6c93ee82016-02-03 04:08:18 +0000156 auto Profile = Writer.writeBuffer();
157 readProfile(std::move(Profile));
158
Easwaran Raman7cefdb82016-05-19 21:53:28 +0000159 auto VerifySummary = [](ProfileSummary &IPS) mutable {
160 ASSERT_EQ(ProfileSummary::PSK_Instr, IPS.getKind());
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000161 ASSERT_EQ(2305843009213693952U, IPS.getMaxFunctionCount());
Easwaran Raman7cefdb82016-05-19 21:53:28 +0000162 ASSERT_EQ(2305843009213693952U, IPS.getMaxCount());
163 ASSERT_EQ(10U, IPS.getNumCounts());
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000164 ASSERT_EQ(4539628424389557499U, IPS.getTotalCount());
165 std::vector<ProfileSummaryEntry> &Details = IPS.getDetailedSummary();
166 uint32_t Cutoff = 800000;
167 auto Predicate = [&Cutoff](const ProfileSummaryEntry &PE) {
168 return PE.Cutoff == Cutoff;
169 };
David Majnemer562e8292016-08-12 00:18:03 +0000170 auto EightyPerc = find_if(Details, Predicate);
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000171 Cutoff = 900000;
David Majnemer562e8292016-08-12 00:18:03 +0000172 auto NinetyPerc = find_if(Details, Predicate);
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000173 Cutoff = 950000;
David Majnemer562e8292016-08-12 00:18:03 +0000174 auto NinetyFivePerc = find_if(Details, Predicate);
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000175 Cutoff = 990000;
David Majnemer562e8292016-08-12 00:18:03 +0000176 auto NinetyNinePerc = find_if(Details, Predicate);
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000177 ASSERT_EQ(576460752303423488U, EightyPerc->MinCount);
178 ASSERT_EQ(288230376151711744U, NinetyPerc->MinCount);
179 ASSERT_EQ(288230376151711744U, NinetyFivePerc->MinCount);
180 ASSERT_EQ(72057594037927936U, NinetyNinePerc->MinCount);
Xinliang David Li6c93ee82016-02-03 04:08:18 +0000181 };
Easwaran Raman7cefdb82016-05-19 21:53:28 +0000182 ProfileSummary &PS = Reader->getSummary();
Easwaran Ramanf9709ee2016-03-14 22:23:28 +0000183 VerifySummary(PS);
Easwaran Raman26628d32016-03-18 21:29:30 +0000184
185 // Test that conversion of summary to and from Metadata works.
Mehdi Amini03b42e42016-04-14 21:59:01 +0000186 LLVMContext Context;
187 Metadata *MD = PS.getMD(Context);
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000188 ASSERT_TRUE(MD);
189 ProfileSummary *PSFromMD = ProfileSummary::getFromMD(MD);
190 ASSERT_TRUE(PSFromMD);
Easwaran Raman7cefdb82016-05-19 21:53:28 +0000191 VerifySummary(*PSFromMD);
192 delete PSFromMD;
Easwaran Raman26628d32016-03-18 21:29:30 +0000193
194 // Test that summary can be attached to and read back from module.
Mehdi Amini03b42e42016-04-14 21:59:01 +0000195 Module M("my_module", Context);
Easwaran Raman26628d32016-03-18 21:29:30 +0000196 M.setProfileSummary(MD);
197 MD = M.getProfileSummary();
198 ASSERT_TRUE(MD);
199 PSFromMD = ProfileSummary::getFromMD(MD);
200 ASSERT_TRUE(PSFromMD);
Easwaran Raman7cefdb82016-05-19 21:53:28 +0000201 VerifySummary(*PSFromMD);
202 delete PSFromMD;
Xinliang David Li6c93ee82016-02-03 04:08:18 +0000203}
204
Vedant Kumare3a0bf52016-07-19 01:17:20 +0000205TEST_F(InstrProfTest, test_writer_merge) {
206 InstrProfRecord Record1("func1", 0x1234, {42});
207 NoError(Writer.addRecord(std::move(Record1)));
208
209 InstrProfWriter Writer2;
210 InstrProfRecord Record2("func2", 0x1234, {0, 0});
211 NoError(Writer2.addRecord(std::move(Record2)));
212
213 NoError(Writer.mergeRecordsFromWriter(std::move(Writer2)));
214
215 auto Profile = Writer.writeBuffer();
216 readProfile(std::move(Profile));
217
218 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("func1", 0x1234);
219 ASSERT_TRUE(NoError(R.takeError()));
220 ASSERT_EQ(1U, R->Counts.size());
221 ASSERT_EQ(42U, R->Counts[0]);
222
223 R = Reader->getInstrProfRecord("func2", 0x1234);
224 ASSERT_TRUE(NoError(R.takeError()));
225 ASSERT_EQ(2U, R->Counts.size());
226 ASSERT_EQ(0U, R->Counts[0]);
227 ASSERT_EQ(0U, R->Counts[1]);
228}
229
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000230static const char callee1[] = "callee1";
231static const char callee2[] = "callee2";
232static const char callee3[] = "callee3";
233static const char callee4[] = "callee4";
234static const char callee5[] = "callee5";
235static const char callee6[] = "callee6";
236
Vedant Kumar00dab222016-01-29 22:54:45 +0000237TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write) {
Xinliang David Li2004f002015-11-02 05:08:23 +0000238 InstrProfRecord Record1("caller", 0x1234, {1, 2});
239 InstrProfRecord Record2("callee1", 0x1235, {3, 4});
240 InstrProfRecord Record3("callee2", 0x1235, {3, 4});
241 InstrProfRecord Record4("callee3", 0x1235, {3, 4});
242
243 // 4 value sites.
244 Record1.reserveSites(IPVK_IndirectCallTarget, 4);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000245 InstrProfValueData VD0[] = {
246 {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000247 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
Xinliang David Liee415892015-11-10 00:24:45 +0000248 // No value profile data at the second site.
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000249 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000250 InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000251 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000252 InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000253 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000254
Vedant Kumarec210812016-05-03 17:07:06 +0000255 NoError(Writer.addRecord(std::move(Record1)));
256 NoError(Writer.addRecord(std::move(Record2)));
257 NoError(Writer.addRecord(std::move(Record3)));
258 NoError(Writer.addRecord(std::move(Record4)));
Xinliang David Li2004f002015-11-02 05:08:23 +0000259 auto Profile = Writer.writeBuffer();
260 readProfile(std::move(Profile));
261
Vedant Kumar9152fd12016-05-19 03:54:45 +0000262 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
263 ASSERT_TRUE(NoError(R.takeError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000264 ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
265 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
266 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
267 ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
268 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
Xinliang David Li2004f002015-11-02 05:08:23 +0000269
Xinliang David Li1e4c8092016-02-04 05:29:51 +0000270 uint64_t TotalC;
Xinliang David Li2004f002015-11-02 05:08:23 +0000271 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000272 R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000273
274 ASSERT_EQ(3U, VD[0].Count);
275 ASSERT_EQ(2U, VD[1].Count);
276 ASSERT_EQ(1U, VD[2].Count);
Xinliang David Li1e4c8092016-02-04 05:29:51 +0000277 ASSERT_EQ(6U, TotalC);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000278
279 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
280 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
281 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
282}
283
Xinliang David Li402477d2016-02-04 19:11:43 +0000284TEST_P(MaybeSparseInstrProfTest, annotate_vp_data) {
285 InstrProfRecord Record("caller", 0x1234, {1, 2});
286 Record.reserveSites(IPVK_IndirectCallTarget, 1);
Rong Xu69683f12016-02-10 22:19:43 +0000287 InstrProfValueData VD0[] = {{1000, 1}, {2000, 2}, {3000, 3}, {5000, 5},
288 {4000, 4}, {6000, 6}};
289 Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 6, nullptr);
Vedant Kumarec210812016-05-03 17:07:06 +0000290 NoError(Writer.addRecord(std::move(Record)));
Xinliang David Li402477d2016-02-04 19:11:43 +0000291 auto Profile = Writer.writeBuffer();
292 readProfile(std::move(Profile));
Vedant Kumar9152fd12016-05-19 03:54:45 +0000293 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
294 ASSERT_TRUE(NoError(R.takeError()));
Xinliang David Li402477d2016-02-04 19:11:43 +0000295
296 LLVMContext Ctx;
297 std::unique_ptr<Module> M(new Module("MyModule", Ctx));
298 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
299 /*isVarArg=*/false);
300 Function *F =
301 Function::Create(FTy, Function::ExternalLinkage, "caller", M.get());
302 BasicBlock *BB = BasicBlock::Create(Ctx, "", F);
303
304 IRBuilder<> Builder(BB);
305 BasicBlock *TBB = BasicBlock::Create(Ctx, "", F);
306 BasicBlock *FBB = BasicBlock::Create(Ctx, "", F);
307
308 // Use branch instruction to annotate with value profile data for simplicity
309 Instruction *Inst = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
310 Instruction *Inst2 = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
David Blaikiefed557e2016-02-09 01:02:24 +0000311 annotateValueSite(*M, *Inst, R.get(), IPVK_IndirectCallTarget, 0);
Xinliang David Li402477d2016-02-04 19:11:43 +0000312
313 InstrProfValueData ValueData[5];
314 uint32_t N;
315 uint64_t T;
316 bool Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
317 ValueData, N, T);
318 ASSERT_TRUE(Res);
319 ASSERT_EQ(3U, N);
Rong Xu69683f12016-02-10 22:19:43 +0000320 ASSERT_EQ(21U, T);
Xinliang David Li402477d2016-02-04 19:11:43 +0000321 // The result should be sorted already:
Rong Xu69683f12016-02-10 22:19:43 +0000322 ASSERT_EQ(6000U, ValueData[0].Value);
323 ASSERT_EQ(6U, ValueData[0].Count);
324 ASSERT_EQ(5000U, ValueData[1].Value);
325 ASSERT_EQ(5U, ValueData[1].Count);
326 ASSERT_EQ(4000U, ValueData[2].Value);
327 ASSERT_EQ(4U, ValueData[2].Count);
Xinliang David Li402477d2016-02-04 19:11:43 +0000328 Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 1, ValueData,
329 N, T);
330 ASSERT_TRUE(Res);
331 ASSERT_EQ(1U, N);
Rong Xu69683f12016-02-10 22:19:43 +0000332 ASSERT_EQ(21U, T);
Xinliang David Li402477d2016-02-04 19:11:43 +0000333
334 Res = getValueProfDataFromInst(*Inst2, IPVK_IndirectCallTarget, 5, ValueData,
335 N, T);
336 ASSERT_FALSE(Res);
Rong Xu69683f12016-02-10 22:19:43 +0000337
338 // Remove the MD_prof metadata
339 Inst->setMetadata(LLVMContext::MD_prof, 0);
340 // Annotate 5 records this time.
341 annotateValueSite(*M, *Inst, R.get(), IPVK_IndirectCallTarget, 0, 5);
342 Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
343 ValueData, N, T);
344 ASSERT_TRUE(Res);
345 ASSERT_EQ(5U, N);
346 ASSERT_EQ(21U, T);
347 ASSERT_EQ(6000U, ValueData[0].Value);
348 ASSERT_EQ(6U, ValueData[0].Count);
349 ASSERT_EQ(5000U, ValueData[1].Value);
350 ASSERT_EQ(5U, ValueData[1].Count);
351 ASSERT_EQ(4000U, ValueData[2].Value);
352 ASSERT_EQ(4U, ValueData[2].Count);
353 ASSERT_EQ(3000U, ValueData[3].Value);
354 ASSERT_EQ(3U, ValueData[3].Count);
355 ASSERT_EQ(2000U, ValueData[4].Value);
356 ASSERT_EQ(2U, ValueData[4].Count);
Rong Xubb494902016-02-12 21:36:17 +0000357
358 // Remove the MD_prof metadata
359 Inst->setMetadata(LLVMContext::MD_prof, 0);
360 // Annotate with 4 records.
361 InstrProfValueData VD0Sorted[] = {{1000, 6}, {2000, 5}, {3000, 4}, {4000, 3},
362 {5000, 2}, {6000, 1}};
Rong Xu311ada12016-03-30 16:56:31 +0000363 annotateValueSite(*M, *Inst, makeArrayRef(VD0Sorted).slice(2), 10,
364 IPVK_IndirectCallTarget, 5);
Rong Xubb494902016-02-12 21:36:17 +0000365 Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
366 ValueData, N, T);
367 ASSERT_TRUE(Res);
368 ASSERT_EQ(4U, N);
369 ASSERT_EQ(10U, T);
370 ASSERT_EQ(3000U, ValueData[0].Value);
371 ASSERT_EQ(4U, ValueData[0].Count);
372 ASSERT_EQ(4000U, ValueData[1].Value);
373 ASSERT_EQ(3U, ValueData[1].Count);
374 ASSERT_EQ(5000U, ValueData[2].Value);
375 ASSERT_EQ(2U, ValueData[2].Count);
376 ASSERT_EQ(6000U, ValueData[3].Value);
377 ASSERT_EQ(1U, ValueData[3].Count);
Xinliang David Li402477d2016-02-04 19:11:43 +0000378}
379
Vedant Kumar00dab222016-01-29 22:54:45 +0000380TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_with_weight) {
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000381 InstrProfRecord Record1("caller", 0x1234, {1, 2});
382 InstrProfRecord Record2("callee1", 0x1235, {3, 4});
383 InstrProfRecord Record3("callee2", 0x1235, {3, 4});
384 InstrProfRecord Record4("callee3", 0x1235, {3, 4});
385
386 // 4 value sites.
387 Record1.reserveSites(IPVK_IndirectCallTarget, 4);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000388 InstrProfValueData VD0[] = {
389 {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000390 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
391 // No value profile data at the second site.
392 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000393 InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000394 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000395 InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000396 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
397
Vedant Kumarec210812016-05-03 17:07:06 +0000398 NoError(Writer.addRecord(std::move(Record1), 10));
399 NoError(Writer.addRecord(std::move(Record2)));
400 NoError(Writer.addRecord(std::move(Record3)));
401 NoError(Writer.addRecord(std::move(Record4)));
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000402 auto Profile = Writer.writeBuffer();
403 readProfile(std::move(Profile));
404
Vedant Kumar9152fd12016-05-19 03:54:45 +0000405 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
406 ASSERT_TRUE(NoError(R.takeError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000407 ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
408 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
409 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
410 ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
411 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000412
Xinliang David Li1e4c8092016-02-04 05:29:51 +0000413 uint64_t TotalC;
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000414 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000415 R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000416 ASSERT_EQ(30U, VD[0].Count);
417 ASSERT_EQ(20U, VD[1].Count);
418 ASSERT_EQ(10U, VD[2].Count);
Xinliang David Li1e4c8092016-02-04 05:29:51 +0000419 ASSERT_EQ(60U, TotalC);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000420
Xinliang David Li2004f002015-11-02 05:08:23 +0000421 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
422 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
423 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
424}
425
Vedant Kumar00dab222016-01-29 22:54:45 +0000426TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_big_endian) {
Xinliang David Li46ad3632016-01-22 19:53:31 +0000427 InstrProfRecord Record1("caller", 0x1234, {1, 2});
428 InstrProfRecord Record2("callee1", 0x1235, {3, 4});
429 InstrProfRecord Record3("callee2", 0x1235, {3, 4});
430 InstrProfRecord Record4("callee3", 0x1235, {3, 4});
431
432 // 4 value sites.
433 Record1.reserveSites(IPVK_IndirectCallTarget, 4);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000434 InstrProfValueData VD0[] = {
435 {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
Xinliang David Li46ad3632016-01-22 19:53:31 +0000436 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
437 // No value profile data at the second site.
438 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000439 InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
Xinliang David Li46ad3632016-01-22 19:53:31 +0000440 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000441 InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
Xinliang David Li46ad3632016-01-22 19:53:31 +0000442 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
443
Vedant Kumarec210812016-05-03 17:07:06 +0000444 NoError(Writer.addRecord(std::move(Record1)));
445 NoError(Writer.addRecord(std::move(Record2)));
446 NoError(Writer.addRecord(std::move(Record3)));
447 NoError(Writer.addRecord(std::move(Record4)));
Xinliang David Li46ad3632016-01-22 19:53:31 +0000448
449 // Set big endian output.
450 Writer.setValueProfDataEndianness(support::big);
451
452 auto Profile = Writer.writeBuffer();
453 readProfile(std::move(Profile));
454
455 // Set big endian input.
456 Reader->setValueProfDataEndianness(support::big);
457
Vedant Kumar9152fd12016-05-19 03:54:45 +0000458 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
459 ASSERT_TRUE(NoError(R.takeError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000460 ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
461 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
462 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
463 ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
464 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
Xinliang David Li46ad3632016-01-22 19:53:31 +0000465
466 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000467 R->getValueForSite(IPVK_IndirectCallTarget, 0);
Xinliang David Li46ad3632016-01-22 19:53:31 +0000468 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
469 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
470 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
471
472 // Restore little endian default:
473 Writer.setValueProfDataEndianness(support::little);
474}
475
Vedant Kumar00dab222016-01-29 22:54:45 +0000476TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge1) {
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000477 static const char caller[] = "caller";
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000478 InstrProfRecord Record11(caller, 0x1234, {1, 2});
479 InstrProfRecord Record12(caller, 0x1234, {1, 2});
480 InstrProfRecord Record2(callee1, 0x1235, {3, 4});
481 InstrProfRecord Record3(callee2, 0x1235, {3, 4});
482 InstrProfRecord Record4(callee3, 0x1235, {3, 4});
483 InstrProfRecord Record5(callee3, 0x1235, {3, 4});
484 InstrProfRecord Record6(callee4, 0x1235, {3, 5});
Xinliang David Li2004f002015-11-02 05:08:23 +0000485
486 // 5 value sites.
487 Record11.reserveSites(IPVK_IndirectCallTarget, 5);
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000488 InstrProfValueData VD0[] = {{uint64_t(callee1), 1},
489 {uint64_t(callee2), 2},
490 {uint64_t(callee3), 3},
491 {uint64_t(callee4), 4}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000492 Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 4, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000493
Xinliang David Li872df222016-01-08 06:54:27 +0000494 // No value profile data at the second site.
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000495 Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000496
Xinliang David Li872df222016-01-08 06:54:27 +0000497 InstrProfValueData VD2[] = {
498 {uint64_t(callee1), 1}, {uint64_t(callee2), 2}, {uint64_t(callee3), 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000499 Record11.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000500
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000501 InstrProfValueData VD3[] = {{uint64_t(callee1), 1}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000502 Record11.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000503
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000504 InstrProfValueData VD4[] = {{uint64_t(callee1), 1},
505 {uint64_t(callee2), 2},
506 {uint64_t(callee3), 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000507 Record11.addValueData(IPVK_IndirectCallTarget, 4, VD4, 3, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000508
David Majnemer68318e02016-04-22 06:37:48 +0000509 // A different record for the same caller.
Xinliang David Li2004f002015-11-02 05:08:23 +0000510 Record12.reserveSites(IPVK_IndirectCallTarget, 5);
Xinliang David Li872df222016-01-08 06:54:27 +0000511 InstrProfValueData VD02[] = {{uint64_t(callee2), 5}, {uint64_t(callee3), 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000512 Record12.addValueData(IPVK_IndirectCallTarget, 0, VD02, 2, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000513
Xinliang David Li872df222016-01-08 06:54:27 +0000514 // No value profile data at the second site.
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000515 Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000516
Xinliang David Li872df222016-01-08 06:54:27 +0000517 InstrProfValueData VD22[] = {
518 {uint64_t(callee2), 1}, {uint64_t(callee3), 3}, {uint64_t(callee4), 4}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000519 Record12.addValueData(IPVK_IndirectCallTarget, 2, VD22, 3, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000520
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000521 Record12.addValueData(IPVK_IndirectCallTarget, 3, nullptr, 0, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000522
Xinliang David Li46ad3632016-01-22 19:53:31 +0000523 InstrProfValueData VD42[] = {{uint64_t(callee1), 1},
524 {uint64_t(callee2), 2},
525 {uint64_t(callee3), 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000526 Record12.addValueData(IPVK_IndirectCallTarget, 4, VD42, 3, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000527
Vedant Kumarec210812016-05-03 17:07:06 +0000528 NoError(Writer.addRecord(std::move(Record11)));
Xinliang David Li2004f002015-11-02 05:08:23 +0000529 // Merge profile data.
Vedant Kumarec210812016-05-03 17:07:06 +0000530 NoError(Writer.addRecord(std::move(Record12)));
Xinliang David Li2004f002015-11-02 05:08:23 +0000531
Vedant Kumarec210812016-05-03 17:07:06 +0000532 NoError(Writer.addRecord(std::move(Record2)));
533 NoError(Writer.addRecord(std::move(Record3)));
534 NoError(Writer.addRecord(std::move(Record4)));
535 NoError(Writer.addRecord(std::move(Record5)));
536 NoError(Writer.addRecord(std::move(Record6)));
Xinliang David Li2004f002015-11-02 05:08:23 +0000537 auto Profile = Writer.writeBuffer();
538 readProfile(std::move(Profile));
539
Vedant Kumar9152fd12016-05-19 03:54:45 +0000540 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
541 ASSERT_TRUE(NoError(R.takeError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000542 ASSERT_EQ(5U, R->getNumValueSites(IPVK_IndirectCallTarget));
543 ASSERT_EQ(4U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
544 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
545 ASSERT_EQ(4U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
546 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
547 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 4));
Xinliang David Li2004f002015-11-02 05:08:23 +0000548
549 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000550 R->getValueForSite(IPVK_IndirectCallTarget, 0);
Xinliang David Li2004f002015-11-02 05:08:23 +0000551 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee2"));
552 ASSERT_EQ(7U, VD[0].Count);
553 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee3"));
554 ASSERT_EQ(6U, VD[1].Count);
555 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee4"));
556 ASSERT_EQ(4U, VD[2].Count);
557 ASSERT_EQ(StringRef((const char *)VD[3].Value, 7), StringRef("callee1"));
558 ASSERT_EQ(1U, VD[3].Count);
559
560 std::unique_ptr<InstrProfValueData[]> VD_2(
David Blaikiefed557e2016-02-09 01:02:24 +0000561 R->getValueForSite(IPVK_IndirectCallTarget, 2));
Xinliang David Li2004f002015-11-02 05:08:23 +0000562 ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee3"));
563 ASSERT_EQ(6U, VD_2[0].Count);
564 ASSERT_EQ(StringRef((const char *)VD_2[1].Value, 7), StringRef("callee4"));
565 ASSERT_EQ(4U, VD_2[1].Count);
566 ASSERT_EQ(StringRef((const char *)VD_2[2].Value, 7), StringRef("callee2"));
567 ASSERT_EQ(3U, VD_2[2].Count);
568 ASSERT_EQ(StringRef((const char *)VD_2[3].Value, 7), StringRef("callee1"));
569 ASSERT_EQ(1U, VD_2[3].Count);
570
571 std::unique_ptr<InstrProfValueData[]> VD_3(
David Blaikiefed557e2016-02-09 01:02:24 +0000572 R->getValueForSite(IPVK_IndirectCallTarget, 3));
Xinliang David Li2004f002015-11-02 05:08:23 +0000573 ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee1"));
574 ASSERT_EQ(1U, VD_3[0].Count);
575
576 std::unique_ptr<InstrProfValueData[]> VD_4(
David Blaikiefed557e2016-02-09 01:02:24 +0000577 R->getValueForSite(IPVK_IndirectCallTarget, 4));
Xinliang David Li2004f002015-11-02 05:08:23 +0000578 ASSERT_EQ(StringRef((const char *)VD_4[0].Value, 7), StringRef("callee3"));
579 ASSERT_EQ(6U, VD_4[0].Count);
580 ASSERT_EQ(StringRef((const char *)VD_4[1].Value, 7), StringRef("callee2"));
581 ASSERT_EQ(4U, VD_4[1].Count);
582 ASSERT_EQ(StringRef((const char *)VD_4[2].Value, 7), StringRef("callee1"));
583 ASSERT_EQ(2U, VD_4[2].Count);
584}
585
Vedant Kumar00dab222016-01-29 22:54:45 +0000586TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge1_saturation) {
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000587 static const char bar[] = "bar";
588
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000589 const uint64_t Max = std::numeric_limits<uint64_t>::max();
590
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000591 InstrProfRecord Record1("foo", 0x1234, {1});
592 auto Result1 = Writer.addRecord(std::move(Record1));
Vedant Kumar9152fd12016-05-19 03:54:45 +0000593 ASSERT_EQ(InstrProfError::take(std::move(Result1)),
594 instrprof_error::success);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000595
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000596 // Verify counter overflow.
597 InstrProfRecord Record2("foo", 0x1234, {Max});
598 auto Result2 = Writer.addRecord(std::move(Record2));
Vedant Kumar9152fd12016-05-19 03:54:45 +0000599 ASSERT_EQ(InstrProfError::take(std::move(Result2)),
600 instrprof_error::counter_overflow);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000601
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000602 InstrProfRecord Record3(bar, 0x9012, {8});
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000603 auto Result3 = Writer.addRecord(std::move(Record3));
Vedant Kumar9152fd12016-05-19 03:54:45 +0000604 ASSERT_EQ(InstrProfError::take(std::move(Result3)),
605 instrprof_error::success);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000606
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000607 InstrProfRecord Record4("baz", 0x5678, {3, 4});
608 Record4.reserveSites(IPVK_IndirectCallTarget, 1);
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000609 InstrProfValueData VD4[] = {{uint64_t(bar), 1}};
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000610 Record4.addValueData(IPVK_IndirectCallTarget, 0, VD4, 1, nullptr);
611 auto Result4 = Writer.addRecord(std::move(Record4));
Vedant Kumar9152fd12016-05-19 03:54:45 +0000612 ASSERT_EQ(InstrProfError::take(std::move(Result4)),
613 instrprof_error::success);
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000614
615 // Verify value data counter overflow.
616 InstrProfRecord Record5("baz", 0x5678, {5, 6});
617 Record5.reserveSites(IPVK_IndirectCallTarget, 1);
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000618 InstrProfValueData VD5[] = {{uint64_t(bar), Max}};
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000619 Record5.addValueData(IPVK_IndirectCallTarget, 0, VD5, 1, nullptr);
620 auto Result5 = Writer.addRecord(std::move(Record5));
Vedant Kumar9152fd12016-05-19 03:54:45 +0000621 ASSERT_EQ(InstrProfError::take(std::move(Result5)),
622 instrprof_error::counter_overflow);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000623
624 auto Profile = Writer.writeBuffer();
625 readProfile(std::move(Profile));
626
627 // Verify saturation of counts.
Vedant Kumar9152fd12016-05-19 03:54:45 +0000628 Expected<InstrProfRecord> ReadRecord1 =
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000629 Reader->getInstrProfRecord("foo", 0x1234);
Vedant Kumar9152fd12016-05-19 03:54:45 +0000630 ASSERT_TRUE(NoError(ReadRecord1.takeError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000631 ASSERT_EQ(Max, ReadRecord1->Counts[0]);
Nathan Slingerlandaa5702d2015-12-02 18:19:24 +0000632
Vedant Kumar9152fd12016-05-19 03:54:45 +0000633 Expected<InstrProfRecord> ReadRecord2 =
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000634 Reader->getInstrProfRecord("baz", 0x5678);
Vedant Kumar9152fd12016-05-19 03:54:45 +0000635 ASSERT_TRUE(bool(ReadRecord2));
David Blaikiefed557e2016-02-09 01:02:24 +0000636 ASSERT_EQ(1U, ReadRecord2->getNumValueSites(IPVK_IndirectCallTarget));
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000637 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000638 ReadRecord2->getValueForSite(IPVK_IndirectCallTarget, 0);
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000639 ASSERT_EQ(StringRef("bar"), StringRef((const char *)VD[0].Value, 3));
640 ASSERT_EQ(Max, VD[0].Count);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000641}
642
Xinliang David Li872df222016-01-08 06:54:27 +0000643// This test tests that when there are too many values
644// for a given site, the merged results are properly
645// truncated.
Vedant Kumar00dab222016-01-29 22:54:45 +0000646TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge_site_trunc) {
Xinliang David Li872df222016-01-08 06:54:27 +0000647 static const char caller[] = "caller";
648
649 InstrProfRecord Record11(caller, 0x1234, {1, 2});
650 InstrProfRecord Record12(caller, 0x1234, {1, 2});
651
652 // 2 value sites.
653 Record11.reserveSites(IPVK_IndirectCallTarget, 2);
654 InstrProfValueData VD0[255];
655 for (int I = 0; I < 255; I++) {
656 VD0[I].Value = 2 * I;
657 VD0[I].Count = 2 * I + 1000;
658 }
659
660 Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 255, nullptr);
661 Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
662
663 Record12.reserveSites(IPVK_IndirectCallTarget, 2);
664 InstrProfValueData VD1[255];
665 for (int I = 0; I < 255; I++) {
666 VD1[I].Value = 2 * I + 1;
667 VD1[I].Count = 2 * I + 1001;
668 }
669
670 Record12.addValueData(IPVK_IndirectCallTarget, 0, VD1, 255, nullptr);
671 Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
672
Vedant Kumarec210812016-05-03 17:07:06 +0000673 NoError(Writer.addRecord(std::move(Record11)));
Xinliang David Li872df222016-01-08 06:54:27 +0000674 // Merge profile data.
Vedant Kumarec210812016-05-03 17:07:06 +0000675 NoError(Writer.addRecord(std::move(Record12)));
Xinliang David Li872df222016-01-08 06:54:27 +0000676
677 auto Profile = Writer.writeBuffer();
678 readProfile(std::move(Profile));
679
Vedant Kumar9152fd12016-05-19 03:54:45 +0000680 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
681 ASSERT_TRUE(NoError(R.takeError()));
Xinliang David Li872df222016-01-08 06:54:27 +0000682 std::unique_ptr<InstrProfValueData[]> VD(
David Blaikiefed557e2016-02-09 01:02:24 +0000683 R->getValueForSite(IPVK_IndirectCallTarget, 0));
684 ASSERT_EQ(2U, R->getNumValueSites(IPVK_IndirectCallTarget));
685 ASSERT_EQ(255U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
NAKAMURA Takumi249edf32016-01-08 07:58:20 +0000686 for (unsigned I = 0; I < 255; I++) {
Xinliang David Li872df222016-01-08 06:54:27 +0000687 ASSERT_EQ(VD[I].Value, 509 - I);
688 ASSERT_EQ(VD[I].Count, 1509 - I);
689 }
690}
691
Xinliang David Li8e6b9172016-05-13 00:23:49 +0000692static void addValueProfData(InstrProfRecord &Record) {
693 Record.reserveSites(IPVK_IndirectCallTarget, 5);
694 InstrProfValueData VD0[] = {{uint64_t(callee1), 400},
695 {uint64_t(callee2), 1000},
696 {uint64_t(callee3), 500},
697 {uint64_t(callee4), 300},
698 {uint64_t(callee5), 100}};
699 Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 5, nullptr);
700 InstrProfValueData VD1[] = {{uint64_t(callee5), 800},
701 {uint64_t(callee3), 1000},
702 {uint64_t(callee2), 2500},
703 {uint64_t(callee1), 1300}};
704 Record.addValueData(IPVK_IndirectCallTarget, 1, VD1, 4, nullptr);
705 InstrProfValueData VD2[] = {{uint64_t(callee6), 800},
706 {uint64_t(callee3), 1000},
707 {uint64_t(callee4), 5500}};
708 Record.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr);
709 InstrProfValueData VD3[] = {{uint64_t(callee2), 1800},
710 {uint64_t(callee3), 2000}};
711 Record.addValueData(IPVK_IndirectCallTarget, 3, VD3, 2, nullptr);
712 Record.addValueData(IPVK_IndirectCallTarget, 4, nullptr, 0, nullptr);
713}
Xinliang David Lied966772015-11-25 23:31:18 +0000714
Xinliang David Li8e6b9172016-05-13 00:23:49 +0000715TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write) {
716 InstrProfRecord SrcRecord("caller", 0x1234, {1ULL << 31, 2});
717 addValueProfData(SrcRecord);
718 std::unique_ptr<ValueProfData> VPData =
719 ValueProfData::serializeFrom(SrcRecord);
Xinliang David Lied966772015-11-25 23:31:18 +0000720
721 InstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2});
Eugene Zelenko6ac3f732016-01-26 18:48:36 +0000722 VPData->deserializeTo(Record, nullptr);
Xinliang David Lied966772015-11-25 23:31:18 +0000723
724 // Now read data from Record and sanity check the data
725 ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget));
726 ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
727 ASSERT_EQ(4U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
728 ASSERT_EQ(3U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
729 ASSERT_EQ(2U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
730 ASSERT_EQ(0U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 4));
731
732 auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
733 return VD1.Count > VD2.Count;
734 };
735 std::unique_ptr<InstrProfValueData[]> VD_0(
736 Record.getValueForSite(IPVK_IndirectCallTarget, 0));
737 std::sort(&VD_0[0], &VD_0[5], Cmp);
738 ASSERT_EQ(StringRef((const char *)VD_0[0].Value, 7), StringRef("callee2"));
739 ASSERT_EQ(1000U, VD_0[0].Count);
740 ASSERT_EQ(StringRef((const char *)VD_0[1].Value, 7), StringRef("callee3"));
741 ASSERT_EQ(500U, VD_0[1].Count);
742 ASSERT_EQ(StringRef((const char *)VD_0[2].Value, 7), StringRef("callee1"));
743 ASSERT_EQ(400U, VD_0[2].Count);
744 ASSERT_EQ(StringRef((const char *)VD_0[3].Value, 7), StringRef("callee4"));
745 ASSERT_EQ(300U, VD_0[3].Count);
746 ASSERT_EQ(StringRef((const char *)VD_0[4].Value, 7), StringRef("callee5"));
747 ASSERT_EQ(100U, VD_0[4].Count);
748
749 std::unique_ptr<InstrProfValueData[]> VD_1(
750 Record.getValueForSite(IPVK_IndirectCallTarget, 1));
751 std::sort(&VD_1[0], &VD_1[4], Cmp);
752 ASSERT_EQ(StringRef((const char *)VD_1[0].Value, 7), StringRef("callee2"));
753 ASSERT_EQ(2500U, VD_1[0].Count);
754 ASSERT_EQ(StringRef((const char *)VD_1[1].Value, 7), StringRef("callee1"));
755 ASSERT_EQ(1300U, VD_1[1].Count);
756 ASSERT_EQ(StringRef((const char *)VD_1[2].Value, 7), StringRef("callee3"));
757 ASSERT_EQ(1000U, VD_1[2].Count);
758 ASSERT_EQ(StringRef((const char *)VD_1[3].Value, 7), StringRef("callee5"));
759 ASSERT_EQ(800U, VD_1[3].Count);
760
761 std::unique_ptr<InstrProfValueData[]> VD_2(
762 Record.getValueForSite(IPVK_IndirectCallTarget, 2));
763 std::sort(&VD_2[0], &VD_2[3], Cmp);
764 ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee4"));
765 ASSERT_EQ(5500U, VD_2[0].Count);
766 ASSERT_EQ(StringRef((const char *)VD_2[1].Value, 7), StringRef("callee3"));
767 ASSERT_EQ(1000U, VD_2[1].Count);
768 ASSERT_EQ(StringRef((const char *)VD_2[2].Value, 7), StringRef("callee6"));
769 ASSERT_EQ(800U, VD_2[2].Count);
770
771 std::unique_ptr<InstrProfValueData[]> VD_3(
772 Record.getValueForSite(IPVK_IndirectCallTarget, 3));
773 std::sort(&VD_3[0], &VD_3[2], Cmp);
774 ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee3"));
775 ASSERT_EQ(2000U, VD_3[0].Count);
776 ASSERT_EQ(StringRef((const char *)VD_3[1].Value, 7), StringRef("callee2"));
777 ASSERT_EQ(1800U, VD_3[1].Count);
Xinliang David Lied966772015-11-25 23:31:18 +0000778}
779
Xinliang David Li8e6b9172016-05-13 00:23:49 +0000780TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write_mapping) {
Xinliang David Li28464482016-04-10 03:32:02 +0000781
Xinliang David Li8e6b9172016-05-13 00:23:49 +0000782 InstrProfRecord SrcRecord("caller", 0x1234, {1ULL << 31, 2});
783 addValueProfData(SrcRecord);
784 std::unique_ptr<ValueProfData> VPData =
785 ValueProfData::serializeFrom(SrcRecord);
Xinliang David Li28464482016-04-10 03:32:02 +0000786
787 InstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2});
788 InstrProfSymtab Symtab;
789 Symtab.mapAddress(uint64_t(callee1), 0x1000ULL);
790 Symtab.mapAddress(uint64_t(callee2), 0x2000ULL);
791 Symtab.mapAddress(uint64_t(callee3), 0x3000ULL);
792 Symtab.mapAddress(uint64_t(callee4), 0x4000ULL);
793 // Missing mapping for callee5
794 Symtab.finalizeSymtab();
795
796 VPData->deserializeTo(Record, &Symtab.getAddrHashMap());
797
798 // Now read data from Record and sanity check the data
Xinliang David Li8e6b9172016-05-13 00:23:49 +0000799 ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget));
Xinliang David Li28464482016-04-10 03:32:02 +0000800 ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
801
802 auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
803 return VD1.Count > VD2.Count;
804 };
805 std::unique_ptr<InstrProfValueData[]> VD_0(
806 Record.getValueForSite(IPVK_IndirectCallTarget, 0));
807 std::sort(&VD_0[0], &VD_0[5], Cmp);
808 ASSERT_EQ(VD_0[0].Value, 0x2000ULL);
809 ASSERT_EQ(1000U, VD_0[0].Count);
810 ASSERT_EQ(VD_0[1].Value, 0x3000ULL);
811 ASSERT_EQ(500U, VD_0[1].Count);
812 ASSERT_EQ(VD_0[2].Value, 0x1000ULL);
813 ASSERT_EQ(400U, VD_0[2].Count);
814
815 // callee5 does not have a mapped value -- default to 0.
816 ASSERT_EQ(VD_0[4].Value, 0ULL);
817}
818
Vedant Kumar00dab222016-01-29 22:54:45 +0000819TEST_P(MaybeSparseInstrProfTest, get_max_function_count) {
Justin Bogner9e9a0572015-09-29 22:13:58 +0000820 InstrProfRecord Record1("foo", 0x1234, {1ULL << 31, 2});
821 InstrProfRecord Record2("bar", 0, {1ULL << 63});
822 InstrProfRecord Record3("baz", 0x5678, {0, 0, 0, 0});
Vedant Kumarec210812016-05-03 17:07:06 +0000823 NoError(Writer.addRecord(std::move(Record1)));
824 NoError(Writer.addRecord(std::move(Record2)));
825 NoError(Writer.addRecord(std::move(Record3)));
Justin Bogner2b6c5372015-02-18 01:58:17 +0000826 auto Profile = Writer.writeBuffer();
827 readProfile(std::move(Profile));
828
829 ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount());
830}
831
Vedant Kumar00dab222016-01-29 22:54:45 +0000832TEST_P(MaybeSparseInstrProfTest, get_weighted_function_counts) {
Nathan Slingerland7f5b47d2015-12-15 17:37:09 +0000833 InstrProfRecord Record1("foo", 0x1234, {1, 2});
834 InstrProfRecord Record2("foo", 0x1235, {3, 4});
Vedant Kumarec210812016-05-03 17:07:06 +0000835 NoError(Writer.addRecord(std::move(Record1), 3));
836 NoError(Writer.addRecord(std::move(Record2), 5));
Nathan Slingerland7f5b47d2015-12-15 17:37:09 +0000837 auto Profile = Writer.writeBuffer();
838 readProfile(std::move(Profile));
839
840 std::vector<uint64_t> Counts;
841 ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1234, Counts)));
842 ASSERT_EQ(2U, Counts.size());
843 ASSERT_EQ(3U, Counts[0]);
844 ASSERT_EQ(6U, Counts[1]);
845
846 ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1235, Counts)));
847 ASSERT_EQ(2U, Counts.size());
848 ASSERT_EQ(15U, Counts[0]);
849 ASSERT_EQ(20U, Counts[1]);
850}
851
Xinliang David Lia0601e72016-02-09 05:47:08 +0000852// Testing symtab creator interface used by indexed profile reader.
Vedant Kumar00dab222016-01-29 22:54:45 +0000853TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_test) {
Xinliang David Li2ee5c4d2015-12-19 07:44:57 +0000854 std::vector<StringRef> FuncNames;
855 FuncNames.push_back("func1");
856 FuncNames.push_back("func2");
857 FuncNames.push_back("func3");
858 FuncNames.push_back("bar1");
859 FuncNames.push_back("bar2");
860 FuncNames.push_back("bar3");
861 InstrProfSymtab Symtab;
862 Symtab.create(FuncNames);
863 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
864 ASSERT_EQ(StringRef("func1"), R);
865 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
866 ASSERT_EQ(StringRef("func2"), R);
867 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
868 ASSERT_EQ(StringRef("func3"), R);
869 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
870 ASSERT_EQ(StringRef("bar1"), R);
871 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
872 ASSERT_EQ(StringRef("bar2"), R);
873 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
874 ASSERT_EQ(StringRef("bar3"), R);
Xinliang David Lic96d3d12015-12-19 18:20:09 +0000875
Xinliang David Li86b4b912016-02-10 06:36:55 +0000876 // negative tests
877 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar4"));
878 ASSERT_EQ(StringRef(), R);
879 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("foo4"));
880 ASSERT_EQ(StringRef(), R);
881
Xinliang David Lic96d3d12015-12-19 18:20:09 +0000882 // Now incrementally update the symtab
883 Symtab.addFuncName("blah_1");
884 Symtab.addFuncName("blah_2");
885 Symtab.addFuncName("blah_3");
886 // Finalize it
887 Symtab.finalizeSymtab();
888
889 // Check again
890 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_1"));
891 ASSERT_EQ(StringRef("blah_1"), R);
892 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_2"));
893 ASSERT_EQ(StringRef("blah_2"), R);
894 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_3"));
895 ASSERT_EQ(StringRef("blah_3"), R);
896 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
897 ASSERT_EQ(StringRef("func1"), R);
898 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
899 ASSERT_EQ(StringRef("func2"), R);
900 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
901 ASSERT_EQ(StringRef("func3"), R);
902 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
903 ASSERT_EQ(StringRef("bar1"), R);
904 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
905 ASSERT_EQ(StringRef("bar2"), R);
906 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
907 ASSERT_EQ(StringRef("bar3"), R);
Xinliang David Li2ee5c4d2015-12-19 07:44:57 +0000908}
909
Xinliang David Lia0601e72016-02-09 05:47:08 +0000910// Testing symtab creator interface used by value profile transformer.
Vedant Kumar00dab222016-01-29 22:54:45 +0000911TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_module_test) {
Xinliang David Li59411db2016-01-20 01:26:34 +0000912 LLVMContext Ctx;
913 std::unique_ptr<Module> M = llvm::make_unique<Module>("MyModule.cpp", Ctx);
914 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
915 /*isVarArg=*/false);
916 Function::Create(FTy, Function::ExternalLinkage, "Gfoo", M.get());
917 Function::Create(FTy, Function::ExternalLinkage, "Gblah", M.get());
918 Function::Create(FTy, Function::ExternalLinkage, "Gbar", M.get());
919 Function::Create(FTy, Function::InternalLinkage, "Ifoo", M.get());
920 Function::Create(FTy, Function::InternalLinkage, "Iblah", M.get());
921 Function::Create(FTy, Function::InternalLinkage, "Ibar", M.get());
922 Function::Create(FTy, Function::PrivateLinkage, "Pfoo", M.get());
923 Function::Create(FTy, Function::PrivateLinkage, "Pblah", M.get());
924 Function::Create(FTy, Function::PrivateLinkage, "Pbar", M.get());
925 Function::Create(FTy, Function::WeakODRLinkage, "Wfoo", M.get());
926 Function::Create(FTy, Function::WeakODRLinkage, "Wblah", M.get());
927 Function::Create(FTy, Function::WeakODRLinkage, "Wbar", M.get());
928
929 InstrProfSymtab ProfSymtab;
David Blaikiefed557e2016-02-09 01:02:24 +0000930 ProfSymtab.create(*M);
Xinliang David Li59411db2016-01-20 01:26:34 +0000931
932 StringRef Funcs[] = {"Gfoo", "Gblah", "Gbar", "Ifoo", "Iblah", "Ibar",
933 "Pfoo", "Pblah", "Pbar", "Wfoo", "Wblah", "Wbar"};
934
935 for (unsigned I = 0; I < sizeof(Funcs) / sizeof(*Funcs); I++) {
936 Function *F = M->getFunction(Funcs[I]);
Eugene Zelenko6ac3f732016-01-26 18:48:36 +0000937 ASSERT_TRUE(F != nullptr);
Xinliang David Lida656fe2016-01-20 02:49:53 +0000938 std::string PGOName = getPGOFuncName(*F);
Xinliang David Li3865fdc2016-01-22 18:13:34 +0000939 uint64_t Key = IndexedInstrProf::ComputeHash(PGOName);
Xinliang David Lida656fe2016-01-20 02:49:53 +0000940 ASSERT_EQ(StringRef(PGOName),
Xinliang David Li3865fdc2016-01-22 18:13:34 +0000941 ProfSymtab.getFuncName(Key));
942 ASSERT_EQ(StringRef(Funcs[I]), ProfSymtab.getOrigFuncName(Key));
Xinliang David Li59411db2016-01-20 01:26:34 +0000943 }
944}
945
Xinliang David Lia0601e72016-02-09 05:47:08 +0000946// Testing symtab serialization and creator/deserialization interface
947// used by coverage map reader, and raw profile reader.
Vedant Kumar00dab222016-01-29 22:54:45 +0000948TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_compression_test) {
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000949 std::vector<std::string> FuncNames1;
950 std::vector<std::string> FuncNames2;
Xinliang David Lic2f25cc42016-02-09 05:36:57 +0000951 for (int I = 0; I < 3; I++) {
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000952 std::string str;
953 raw_string_ostream OS(str);
954 OS << "func_" << I;
955 FuncNames1.push_back(OS.str());
956 str.clear();
Vedant Kumar86705ba2016-03-28 21:06:42 +0000957 OS << "f oooooooooooooo_" << I;
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000958 FuncNames1.push_back(OS.str());
959 str.clear();
960 OS << "BAR_" << I;
961 FuncNames2.push_back(OS.str());
962 str.clear();
963 OS << "BlahblahBlahblahBar_" << I;
964 FuncNames2.push_back(OS.str());
965 }
966
Xinliang David Lidd4ae7b2016-01-29 22:29:15 +0000967 for (bool DoCompression : {false, true}) {
968 // Compressing:
969 std::string FuncNameStrings1;
Vedant Kumarec210812016-05-03 17:07:06 +0000970 NoError(collectPGOFuncNameStrings(
971 FuncNames1, (DoCompression && zlib::isAvailable()), FuncNameStrings1));
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000972
Xinliang David Lidd4ae7b2016-01-29 22:29:15 +0000973 // Compressing:
974 std::string FuncNameStrings2;
Vedant Kumarec210812016-05-03 17:07:06 +0000975 NoError(collectPGOFuncNameStrings(
976 FuncNames2, (DoCompression && zlib::isAvailable()), FuncNameStrings2));
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000977
Xinliang David Lic2f25cc42016-02-09 05:36:57 +0000978 for (int Padding = 0; Padding < 2; Padding++) {
979 // Join with paddings :
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000980 std::string FuncNameStrings = FuncNameStrings1;
981 for (int P = 0; P < Padding; P++) {
982 FuncNameStrings.push_back('\0');
983 }
984 FuncNameStrings += FuncNameStrings2;
985
Xinliang David Li8dec8b12016-01-04 23:59:14 +0000986 // Now decompress:
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000987 InstrProfSymtab Symtab;
Vedant Kumarec210812016-05-03 17:07:06 +0000988 NoError(Symtab.create(StringRef(FuncNameStrings)));
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000989
Xinliang David Li8dec8b12016-01-04 23:59:14 +0000990 // Now do the checks:
991 // First sampling some data points:
Xinliang David Lia8ba7af2016-01-29 21:26:31 +0000992 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[0]));
Xinliang David Li8dec8b12016-01-04 23:59:14 +0000993 ASSERT_EQ(StringRef("func_0"), R);
994 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[1]));
Vedant Kumar86705ba2016-03-28 21:06:42 +0000995 ASSERT_EQ(StringRef("f oooooooooooooo_0"), R);
Xinliang David Lic2f25cc42016-02-09 05:36:57 +0000996 for (int I = 0; I < 3; I++) {
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000997 std::string N[4];
998 N[0] = FuncNames1[2 * I];
999 N[1] = FuncNames1[2 * I + 1];
1000 N[2] = FuncNames2[2 * I];
1001 N[3] = FuncNames2[2 * I + 1];
1002 for (int J = 0; J < 4; J++) {
1003 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(N[J]));
1004 ASSERT_EQ(StringRef(N[J]), R);
1005 }
1006 }
1007 }
1008 }
1009}
1010
Vedant Kumar00dab222016-01-29 22:54:45 +00001011TEST_F(SparseInstrProfTest, preserve_no_records) {
1012 InstrProfRecord Record1("foo", 0x1234, {0});
1013 InstrProfRecord Record2("bar", 0x4321, {0, 0});
1014 InstrProfRecord Record3("bar", 0x4321, {0, 0, 0});
1015
Vedant Kumarec210812016-05-03 17:07:06 +00001016 NoError(Writer.addRecord(std::move(Record1)));
1017 NoError(Writer.addRecord(std::move(Record2)));
1018 NoError(Writer.addRecord(std::move(Record3)));
Vedant Kumar00dab222016-01-29 22:54:45 +00001019 auto Profile = Writer.writeBuffer();
1020 readProfile(std::move(Profile));
1021
1022 auto I = Reader->begin(), E = Reader->end();
1023 ASSERT_TRUE(I == E);
1024}
1025
1026INSTANTIATE_TEST_CASE_P(MaybeSparse, MaybeSparseInstrProfTest,
1027 ::testing::Bool());
1028
Justin Bogner2b6c5372015-02-18 01:58:17 +00001029} // end anonymous namespace