blob: a5c9a828d528977c98abb572ee505223acfe1026 [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) {
David Blaikie5b079d82017-07-06 05:19:17 +000073 NoError(Writer.addRecord({"foo", 0x1234, {1, 2, 3, 4}}));
Justin Bogner2b6c5372015-02-18 01:58:17 +000074 auto Profile = Writer.writeBuffer();
75 readProfile(std::move(Profile));
76
77 auto I = Reader->begin(), E = Reader->end();
78 ASSERT_TRUE(I != E);
79 ASSERT_EQ(StringRef("foo"), I->Name);
80 ASSERT_EQ(0x1234U, I->Hash);
81 ASSERT_EQ(4U, I->Counts.size());
82 ASSERT_EQ(1U, I->Counts[0]);
83 ASSERT_EQ(2U, I->Counts[1]);
84 ASSERT_EQ(3U, I->Counts[2]);
85 ASSERT_EQ(4U, I->Counts[3]);
86 ASSERT_TRUE(++I == E);
87}
88
Vedant Kumar00dab222016-01-29 22:54:45 +000089TEST_P(MaybeSparseInstrProfTest, get_instr_prof_record) {
David Blaikie5b079d82017-07-06 05:19:17 +000090 NoError(Writer.addRecord({"foo", 0x1234, {1, 2}}));
91 NoError(Writer.addRecord({"foo", 0x1235, {3, 4}}));
Xinliang David Li2004f002015-11-02 05:08:23 +000092 auto Profile = Writer.writeBuffer();
93 readProfile(std::move(Profile));
94
Vedant Kumar9152fd12016-05-19 03:54:45 +000095 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("foo", 0x1234);
96 ASSERT_TRUE(NoError(R.takeError()));
David Blaikiefed557e2016-02-09 01:02:24 +000097 ASSERT_EQ(2U, R->Counts.size());
98 ASSERT_EQ(1U, R->Counts[0]);
99 ASSERT_EQ(2U, R->Counts[1]);
Xinliang David Li2004f002015-11-02 05:08:23 +0000100
101 R = Reader->getInstrProfRecord("foo", 0x1235);
Vedant Kumar9152fd12016-05-19 03:54:45 +0000102 ASSERT_TRUE(NoError(R.takeError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000103 ASSERT_EQ(2U, R->Counts.size());
104 ASSERT_EQ(3U, R->Counts[0]);
105 ASSERT_EQ(4U, R->Counts[1]);
Xinliang David Li2004f002015-11-02 05:08:23 +0000106
107 R = Reader->getInstrProfRecord("foo", 0x5678);
Vedant Kumar9152fd12016-05-19 03:54:45 +0000108 ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, R.takeError()));
Xinliang David Li2004f002015-11-02 05:08:23 +0000109
110 R = Reader->getInstrProfRecord("bar", 0x1234);
Vedant Kumar9152fd12016-05-19 03:54:45 +0000111 ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, R.takeError()));
Xinliang David Li2004f002015-11-02 05:08:23 +0000112}
113
Vedant Kumar00dab222016-01-29 22:54:45 +0000114TEST_P(MaybeSparseInstrProfTest, get_function_counts) {
David Blaikie5b079d82017-07-06 05:19:17 +0000115 NoError(Writer.addRecord({"foo", 0x1234, {1, 2}}));
116 NoError(Writer.addRecord({"foo", 0x1235, {3, 4}}));
Justin Bogner2b6c5372015-02-18 01:58:17 +0000117 auto Profile = Writer.writeBuffer();
118 readProfile(std::move(Profile));
119
120 std::vector<uint64_t> Counts;
121 ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1234, Counts)));
122 ASSERT_EQ(2U, Counts.size());
123 ASSERT_EQ(1U, Counts[0]);
124 ASSERT_EQ(2U, Counts[1]);
125
Justin Bogner09829f42015-06-22 23:56:53 +0000126 ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1235, Counts)));
127 ASSERT_EQ(2U, Counts.size());
128 ASSERT_EQ(3U, Counts[0]);
129 ASSERT_EQ(4U, Counts[1]);
130
Vedant Kumar9152fd12016-05-19 03:54:45 +0000131 Error E1 = Reader->getFunctionCounts("foo", 0x5678, Counts);
132 ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, std::move(E1)));
Justin Bogner2b6c5372015-02-18 01:58:17 +0000133
Vedant Kumar9152fd12016-05-19 03:54:45 +0000134 Error E2 = Reader->getFunctionCounts("bar", 0x1234, Counts);
135 ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, std::move(E2)));
Justin Bogner2b6c5372015-02-18 01:58:17 +0000136}
137
Xinliang David Li6c93ee82016-02-03 04:08:18 +0000138// Profile data is copied from general.proftext
139TEST_F(InstrProfTest, get_profile_summary) {
David Blaikie5b079d82017-07-06 05:19:17 +0000140 NoError(Writer.addRecord({"func1", 0x1234, {97531}}));
141 NoError(Writer.addRecord({"func2", 0x1234, {0, 0}}));
142 NoError(Writer.addRecord(
143 {"func3",
144 0x1234,
145 {2305843009213693952, 1152921504606846976, 576460752303423488,
146 288230376151711744, 144115188075855872, 72057594037927936}}));
147 NoError(Writer.addRecord({"func4", 0x1234, {0}}));
Xinliang David Li6c93ee82016-02-03 04:08:18 +0000148 auto Profile = Writer.writeBuffer();
149 readProfile(std::move(Profile));
150
Easwaran Raman7cefdb82016-05-19 21:53:28 +0000151 auto VerifySummary = [](ProfileSummary &IPS) mutable {
152 ASSERT_EQ(ProfileSummary::PSK_Instr, IPS.getKind());
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000153 ASSERT_EQ(2305843009213693952U, IPS.getMaxFunctionCount());
Easwaran Raman7cefdb82016-05-19 21:53:28 +0000154 ASSERT_EQ(2305843009213693952U, IPS.getMaxCount());
155 ASSERT_EQ(10U, IPS.getNumCounts());
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000156 ASSERT_EQ(4539628424389557499U, IPS.getTotalCount());
157 std::vector<ProfileSummaryEntry> &Details = IPS.getDetailedSummary();
158 uint32_t Cutoff = 800000;
159 auto Predicate = [&Cutoff](const ProfileSummaryEntry &PE) {
160 return PE.Cutoff == Cutoff;
161 };
David Majnemer562e8292016-08-12 00:18:03 +0000162 auto EightyPerc = find_if(Details, Predicate);
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000163 Cutoff = 900000;
David Majnemer562e8292016-08-12 00:18:03 +0000164 auto NinetyPerc = find_if(Details, Predicate);
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000165 Cutoff = 950000;
David Majnemer562e8292016-08-12 00:18:03 +0000166 auto NinetyFivePerc = find_if(Details, Predicate);
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000167 Cutoff = 990000;
David Majnemer562e8292016-08-12 00:18:03 +0000168 auto NinetyNinePerc = find_if(Details, Predicate);
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000169 ASSERT_EQ(576460752303423488U, EightyPerc->MinCount);
170 ASSERT_EQ(288230376151711744U, NinetyPerc->MinCount);
171 ASSERT_EQ(288230376151711744U, NinetyFivePerc->MinCount);
172 ASSERT_EQ(72057594037927936U, NinetyNinePerc->MinCount);
Xinliang David Li6c93ee82016-02-03 04:08:18 +0000173 };
Easwaran Raman7cefdb82016-05-19 21:53:28 +0000174 ProfileSummary &PS = Reader->getSummary();
Easwaran Ramanf9709ee2016-03-14 22:23:28 +0000175 VerifySummary(PS);
Easwaran Raman26628d32016-03-18 21:29:30 +0000176
177 // Test that conversion of summary to and from Metadata works.
Mehdi Amini03b42e42016-04-14 21:59:01 +0000178 LLVMContext Context;
179 Metadata *MD = PS.getMD(Context);
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000180 ASSERT_TRUE(MD);
181 ProfileSummary *PSFromMD = ProfileSummary::getFromMD(MD);
182 ASSERT_TRUE(PSFromMD);
Easwaran Raman7cefdb82016-05-19 21:53:28 +0000183 VerifySummary(*PSFromMD);
184 delete PSFromMD;
Easwaran Raman26628d32016-03-18 21:29:30 +0000185
186 // Test that summary can be attached to and read back from module.
Mehdi Amini03b42e42016-04-14 21:59:01 +0000187 Module M("my_module", Context);
Easwaran Raman26628d32016-03-18 21:29:30 +0000188 M.setProfileSummary(MD);
189 MD = M.getProfileSummary();
190 ASSERT_TRUE(MD);
191 PSFromMD = ProfileSummary::getFromMD(MD);
192 ASSERT_TRUE(PSFromMD);
Easwaran Raman7cefdb82016-05-19 21:53:28 +0000193 VerifySummary(*PSFromMD);
194 delete PSFromMD;
Xinliang David Li6c93ee82016-02-03 04:08:18 +0000195}
196
Vedant Kumare3a0bf52016-07-19 01:17:20 +0000197TEST_F(InstrProfTest, test_writer_merge) {
David Blaikie5b079d82017-07-06 05:19:17 +0000198 NoError(Writer.addRecord({"func1", 0x1234, {42}}));
Vedant Kumare3a0bf52016-07-19 01:17:20 +0000199
200 InstrProfWriter Writer2;
David Blaikie5b079d82017-07-06 05:19:17 +0000201 NoError(Writer2.addRecord({"func2", 0x1234, {0, 0}}));
Vedant Kumare3a0bf52016-07-19 01:17:20 +0000202
203 NoError(Writer.mergeRecordsFromWriter(std::move(Writer2)));
204
205 auto Profile = Writer.writeBuffer();
206 readProfile(std::move(Profile));
207
208 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("func1", 0x1234);
209 ASSERT_TRUE(NoError(R.takeError()));
210 ASSERT_EQ(1U, R->Counts.size());
211 ASSERT_EQ(42U, R->Counts[0]);
212
213 R = Reader->getInstrProfRecord("func2", 0x1234);
214 ASSERT_TRUE(NoError(R.takeError()));
215 ASSERT_EQ(2U, R->Counts.size());
216 ASSERT_EQ(0U, R->Counts[0]);
217 ASSERT_EQ(0U, R->Counts[1]);
218}
219
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000220static const char callee1[] = "callee1";
221static const char callee2[] = "callee2";
222static const char callee3[] = "callee3";
223static const char callee4[] = "callee4";
224static const char callee5[] = "callee5";
225static const char callee6[] = "callee6";
226
Vedant Kumar00dab222016-01-29 22:54:45 +0000227TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write) {
David Blaikiecf9d52c2017-07-06 19:00:12 +0000228 NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
Xinliang David Li2004f002015-11-02 05:08:23 +0000229
230 // 4 value sites.
231 Record1.reserveSites(IPVK_IndirectCallTarget, 4);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000232 InstrProfValueData VD0[] = {
233 {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000234 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
Xinliang David Liee415892015-11-10 00:24:45 +0000235 // No value profile data at the second site.
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000236 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000237 InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000238 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000239 InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000240 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000241
Vedant Kumarec210812016-05-03 17:07:06 +0000242 NoError(Writer.addRecord(std::move(Record1)));
David Blaikie5b079d82017-07-06 05:19:17 +0000243 NoError(Writer.addRecord({"callee1", 0x1235, {3, 4}}));
244 NoError(Writer.addRecord({"callee2", 0x1235, {3, 4}}));
245 NoError(Writer.addRecord({"callee3", 0x1235, {3, 4}}));
Xinliang David Li2004f002015-11-02 05:08:23 +0000246 auto Profile = Writer.writeBuffer();
247 readProfile(std::move(Profile));
248
Vedant Kumar9152fd12016-05-19 03:54:45 +0000249 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
250 ASSERT_TRUE(NoError(R.takeError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000251 ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
252 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
253 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
254 ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
255 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
Xinliang David Li2004f002015-11-02 05:08:23 +0000256
Xinliang David Li1e4c8092016-02-04 05:29:51 +0000257 uint64_t TotalC;
Xinliang David Li2004f002015-11-02 05:08:23 +0000258 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000259 R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000260
261 ASSERT_EQ(3U, VD[0].Count);
262 ASSERT_EQ(2U, VD[1].Count);
263 ASSERT_EQ(1U, VD[2].Count);
Xinliang David Li1e4c8092016-02-04 05:29:51 +0000264 ASSERT_EQ(6U, TotalC);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000265
266 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
267 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
268 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
269}
270
Xinliang David Li402477d2016-02-04 19:11:43 +0000271TEST_P(MaybeSparseInstrProfTest, annotate_vp_data) {
David Blaikiecf9d52c2017-07-06 19:00:12 +0000272 NamedInstrProfRecord Record("caller", 0x1234, {1, 2});
Xinliang David Li402477d2016-02-04 19:11:43 +0000273 Record.reserveSites(IPVK_IndirectCallTarget, 1);
Rong Xu69683f12016-02-10 22:19:43 +0000274 InstrProfValueData VD0[] = {{1000, 1}, {2000, 2}, {3000, 3}, {5000, 5},
275 {4000, 4}, {6000, 6}};
276 Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 6, nullptr);
Vedant Kumarec210812016-05-03 17:07:06 +0000277 NoError(Writer.addRecord(std::move(Record)));
Xinliang David Li402477d2016-02-04 19:11:43 +0000278 auto Profile = Writer.writeBuffer();
279 readProfile(std::move(Profile));
Vedant Kumar9152fd12016-05-19 03:54:45 +0000280 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
281 ASSERT_TRUE(NoError(R.takeError()));
Xinliang David Li402477d2016-02-04 19:11:43 +0000282
283 LLVMContext Ctx;
284 std::unique_ptr<Module> M(new Module("MyModule", Ctx));
285 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
286 /*isVarArg=*/false);
287 Function *F =
288 Function::Create(FTy, Function::ExternalLinkage, "caller", M.get());
289 BasicBlock *BB = BasicBlock::Create(Ctx, "", F);
290
291 IRBuilder<> Builder(BB);
292 BasicBlock *TBB = BasicBlock::Create(Ctx, "", F);
293 BasicBlock *FBB = BasicBlock::Create(Ctx, "", F);
294
295 // Use branch instruction to annotate with value profile data for simplicity
296 Instruction *Inst = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
297 Instruction *Inst2 = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
David Blaikiefed557e2016-02-09 01:02:24 +0000298 annotateValueSite(*M, *Inst, R.get(), IPVK_IndirectCallTarget, 0);
Xinliang David Li402477d2016-02-04 19:11:43 +0000299
300 InstrProfValueData ValueData[5];
301 uint32_t N;
302 uint64_t T;
303 bool Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
304 ValueData, N, T);
305 ASSERT_TRUE(Res);
306 ASSERT_EQ(3U, N);
Rong Xu69683f12016-02-10 22:19:43 +0000307 ASSERT_EQ(21U, T);
Xinliang David Li402477d2016-02-04 19:11:43 +0000308 // The result should be sorted already:
Rong Xu69683f12016-02-10 22:19:43 +0000309 ASSERT_EQ(6000U, ValueData[0].Value);
310 ASSERT_EQ(6U, ValueData[0].Count);
311 ASSERT_EQ(5000U, ValueData[1].Value);
312 ASSERT_EQ(5U, ValueData[1].Count);
313 ASSERT_EQ(4000U, ValueData[2].Value);
314 ASSERT_EQ(4U, ValueData[2].Count);
Xinliang David Li402477d2016-02-04 19:11:43 +0000315 Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 1, ValueData,
316 N, T);
317 ASSERT_TRUE(Res);
318 ASSERT_EQ(1U, N);
Rong Xu69683f12016-02-10 22:19:43 +0000319 ASSERT_EQ(21U, T);
Xinliang David Li402477d2016-02-04 19:11:43 +0000320
321 Res = getValueProfDataFromInst(*Inst2, IPVK_IndirectCallTarget, 5, ValueData,
322 N, T);
323 ASSERT_FALSE(Res);
Rong Xu69683f12016-02-10 22:19:43 +0000324
325 // Remove the MD_prof metadata
326 Inst->setMetadata(LLVMContext::MD_prof, 0);
327 // Annotate 5 records this time.
328 annotateValueSite(*M, *Inst, R.get(), IPVK_IndirectCallTarget, 0, 5);
329 Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
330 ValueData, N, T);
331 ASSERT_TRUE(Res);
332 ASSERT_EQ(5U, N);
333 ASSERT_EQ(21U, T);
334 ASSERT_EQ(6000U, ValueData[0].Value);
335 ASSERT_EQ(6U, ValueData[0].Count);
336 ASSERT_EQ(5000U, ValueData[1].Value);
337 ASSERT_EQ(5U, ValueData[1].Count);
338 ASSERT_EQ(4000U, ValueData[2].Value);
339 ASSERT_EQ(4U, ValueData[2].Count);
340 ASSERT_EQ(3000U, ValueData[3].Value);
341 ASSERT_EQ(3U, ValueData[3].Count);
342 ASSERT_EQ(2000U, ValueData[4].Value);
343 ASSERT_EQ(2U, ValueData[4].Count);
Rong Xubb494902016-02-12 21:36:17 +0000344
345 // Remove the MD_prof metadata
346 Inst->setMetadata(LLVMContext::MD_prof, 0);
347 // Annotate with 4 records.
348 InstrProfValueData VD0Sorted[] = {{1000, 6}, {2000, 5}, {3000, 4}, {4000, 3},
349 {5000, 2}, {6000, 1}};
Rong Xu311ada12016-03-30 16:56:31 +0000350 annotateValueSite(*M, *Inst, makeArrayRef(VD0Sorted).slice(2), 10,
351 IPVK_IndirectCallTarget, 5);
Rong Xubb494902016-02-12 21:36:17 +0000352 Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
353 ValueData, N, T);
354 ASSERT_TRUE(Res);
355 ASSERT_EQ(4U, N);
356 ASSERT_EQ(10U, T);
357 ASSERT_EQ(3000U, ValueData[0].Value);
358 ASSERT_EQ(4U, ValueData[0].Count);
359 ASSERT_EQ(4000U, ValueData[1].Value);
360 ASSERT_EQ(3U, ValueData[1].Count);
361 ASSERT_EQ(5000U, ValueData[2].Value);
362 ASSERT_EQ(2U, ValueData[2].Count);
363 ASSERT_EQ(6000U, ValueData[3].Value);
364 ASSERT_EQ(1U, ValueData[3].Count);
Xinliang David Li402477d2016-02-04 19:11:43 +0000365}
366
Vedant Kumar00dab222016-01-29 22:54:45 +0000367TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_with_weight) {
David Blaikiecf9d52c2017-07-06 19:00:12 +0000368 NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000369
370 // 4 value sites.
371 Record1.reserveSites(IPVK_IndirectCallTarget, 4);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000372 InstrProfValueData VD0[] = {
373 {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000374 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
375 // No value profile data at the second site.
376 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000377 InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000378 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000379 InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000380 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
381
Vedant Kumarec210812016-05-03 17:07:06 +0000382 NoError(Writer.addRecord(std::move(Record1), 10));
David Blaikie5b079d82017-07-06 05:19:17 +0000383 NoError(Writer.addRecord({"callee1", 0x1235, {3, 4}}));
384 NoError(Writer.addRecord({"callee2", 0x1235, {3, 4}}));
385 NoError(Writer.addRecord({"callee3", 0x1235, {3, 4}}));
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000386 auto Profile = Writer.writeBuffer();
387 readProfile(std::move(Profile));
388
Vedant Kumar9152fd12016-05-19 03:54:45 +0000389 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
390 ASSERT_TRUE(NoError(R.takeError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000391 ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
392 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
393 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
394 ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
395 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000396
Xinliang David Li1e4c8092016-02-04 05:29:51 +0000397 uint64_t TotalC;
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000398 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000399 R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000400 ASSERT_EQ(30U, VD[0].Count);
401 ASSERT_EQ(20U, VD[1].Count);
402 ASSERT_EQ(10U, VD[2].Count);
Xinliang David Li1e4c8092016-02-04 05:29:51 +0000403 ASSERT_EQ(60U, TotalC);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000404
Xinliang David Li2004f002015-11-02 05:08:23 +0000405 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
406 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
407 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
408}
409
Vedant Kumar00dab222016-01-29 22:54:45 +0000410TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_big_endian) {
David Blaikiecf9d52c2017-07-06 19:00:12 +0000411 NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
Xinliang David Li46ad3632016-01-22 19:53:31 +0000412
413 // 4 value sites.
414 Record1.reserveSites(IPVK_IndirectCallTarget, 4);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000415 InstrProfValueData VD0[] = {
416 {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
Xinliang David Li46ad3632016-01-22 19:53:31 +0000417 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
418 // No value profile data at the second site.
419 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000420 InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
Xinliang David Li46ad3632016-01-22 19:53:31 +0000421 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000422 InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
Xinliang David Li46ad3632016-01-22 19:53:31 +0000423 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
424
Vedant Kumarec210812016-05-03 17:07:06 +0000425 NoError(Writer.addRecord(std::move(Record1)));
David Blaikie5b079d82017-07-06 05:19:17 +0000426 NoError(Writer.addRecord({"callee1", 0x1235, {3, 4}}));
427 NoError(Writer.addRecord({"callee2", 0x1235, {3, 4}}));
428 NoError(Writer.addRecord({"callee3", 0x1235, {3, 4}}));
Xinliang David Li46ad3632016-01-22 19:53:31 +0000429
430 // Set big endian output.
431 Writer.setValueProfDataEndianness(support::big);
432
433 auto Profile = Writer.writeBuffer();
434 readProfile(std::move(Profile));
435
436 // Set big endian input.
437 Reader->setValueProfDataEndianness(support::big);
438
Vedant Kumar9152fd12016-05-19 03:54:45 +0000439 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
440 ASSERT_TRUE(NoError(R.takeError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000441 ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
442 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
443 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
444 ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
445 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
Xinliang David Li46ad3632016-01-22 19:53:31 +0000446
447 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000448 R->getValueForSite(IPVK_IndirectCallTarget, 0);
Xinliang David Li46ad3632016-01-22 19:53:31 +0000449 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
450 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
451 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
452
453 // Restore little endian default:
454 Writer.setValueProfDataEndianness(support::little);
455}
456
Vedant Kumar00dab222016-01-29 22:54:45 +0000457TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge1) {
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000458 static const char caller[] = "caller";
David Blaikiecf9d52c2017-07-06 19:00:12 +0000459 NamedInstrProfRecord Record11(caller, 0x1234, {1, 2});
460 NamedInstrProfRecord Record12(caller, 0x1234, {1, 2});
Xinliang David Li2004f002015-11-02 05:08:23 +0000461
462 // 5 value sites.
463 Record11.reserveSites(IPVK_IndirectCallTarget, 5);
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000464 InstrProfValueData VD0[] = {{uint64_t(callee1), 1},
465 {uint64_t(callee2), 2},
466 {uint64_t(callee3), 3},
467 {uint64_t(callee4), 4}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000468 Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 4, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000469
Xinliang David Li872df222016-01-08 06:54:27 +0000470 // No value profile data at the second site.
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000471 Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000472
Xinliang David Li872df222016-01-08 06:54:27 +0000473 InstrProfValueData VD2[] = {
474 {uint64_t(callee1), 1}, {uint64_t(callee2), 2}, {uint64_t(callee3), 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000475 Record11.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000476
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000477 InstrProfValueData VD3[] = {{uint64_t(callee1), 1}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000478 Record11.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000479
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000480 InstrProfValueData VD4[] = {{uint64_t(callee1), 1},
481 {uint64_t(callee2), 2},
482 {uint64_t(callee3), 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000483 Record11.addValueData(IPVK_IndirectCallTarget, 4, VD4, 3, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000484
David Majnemer68318e02016-04-22 06:37:48 +0000485 // A different record for the same caller.
Xinliang David Li2004f002015-11-02 05:08:23 +0000486 Record12.reserveSites(IPVK_IndirectCallTarget, 5);
Xinliang David Li872df222016-01-08 06:54:27 +0000487 InstrProfValueData VD02[] = {{uint64_t(callee2), 5}, {uint64_t(callee3), 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000488 Record12.addValueData(IPVK_IndirectCallTarget, 0, VD02, 2, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000489
Xinliang David Li872df222016-01-08 06:54:27 +0000490 // No value profile data at the second site.
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000491 Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000492
Xinliang David Li872df222016-01-08 06:54:27 +0000493 InstrProfValueData VD22[] = {
494 {uint64_t(callee2), 1}, {uint64_t(callee3), 3}, {uint64_t(callee4), 4}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000495 Record12.addValueData(IPVK_IndirectCallTarget, 2, VD22, 3, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000496
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000497 Record12.addValueData(IPVK_IndirectCallTarget, 3, nullptr, 0, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000498
Xinliang David Li46ad3632016-01-22 19:53:31 +0000499 InstrProfValueData VD42[] = {{uint64_t(callee1), 1},
500 {uint64_t(callee2), 2},
501 {uint64_t(callee3), 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000502 Record12.addValueData(IPVK_IndirectCallTarget, 4, VD42, 3, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000503
Vedant Kumarec210812016-05-03 17:07:06 +0000504 NoError(Writer.addRecord(std::move(Record11)));
Xinliang David Li2004f002015-11-02 05:08:23 +0000505 // Merge profile data.
Vedant Kumarec210812016-05-03 17:07:06 +0000506 NoError(Writer.addRecord(std::move(Record12)));
Xinliang David Li2004f002015-11-02 05:08:23 +0000507
David Blaikie5b079d82017-07-06 05:19:17 +0000508 NoError(Writer.addRecord({callee1, 0x1235, {3, 4}}));
509 NoError(Writer.addRecord({callee2, 0x1235, {3, 4}}));
510 NoError(Writer.addRecord({callee3, 0x1235, {3, 4}}));
511 NoError(Writer.addRecord({callee3, 0x1235, {3, 4}}));
512 NoError(Writer.addRecord({callee4, 0x1235, {3, 5}}));
Xinliang David Li2004f002015-11-02 05:08:23 +0000513 auto Profile = Writer.writeBuffer();
514 readProfile(std::move(Profile));
515
Vedant Kumar9152fd12016-05-19 03:54:45 +0000516 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
517 ASSERT_TRUE(NoError(R.takeError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000518 ASSERT_EQ(5U, R->getNumValueSites(IPVK_IndirectCallTarget));
519 ASSERT_EQ(4U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
520 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
521 ASSERT_EQ(4U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
522 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
523 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 4));
Xinliang David Li2004f002015-11-02 05:08:23 +0000524
525 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000526 R->getValueForSite(IPVK_IndirectCallTarget, 0);
Xinliang David Li2004f002015-11-02 05:08:23 +0000527 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee2"));
528 ASSERT_EQ(7U, VD[0].Count);
529 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee3"));
530 ASSERT_EQ(6U, VD[1].Count);
531 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee4"));
532 ASSERT_EQ(4U, VD[2].Count);
533 ASSERT_EQ(StringRef((const char *)VD[3].Value, 7), StringRef("callee1"));
534 ASSERT_EQ(1U, VD[3].Count);
535
536 std::unique_ptr<InstrProfValueData[]> VD_2(
David Blaikiefed557e2016-02-09 01:02:24 +0000537 R->getValueForSite(IPVK_IndirectCallTarget, 2));
Xinliang David Li2004f002015-11-02 05:08:23 +0000538 ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee3"));
539 ASSERT_EQ(6U, VD_2[0].Count);
540 ASSERT_EQ(StringRef((const char *)VD_2[1].Value, 7), StringRef("callee4"));
541 ASSERT_EQ(4U, VD_2[1].Count);
542 ASSERT_EQ(StringRef((const char *)VD_2[2].Value, 7), StringRef("callee2"));
543 ASSERT_EQ(3U, VD_2[2].Count);
544 ASSERT_EQ(StringRef((const char *)VD_2[3].Value, 7), StringRef("callee1"));
545 ASSERT_EQ(1U, VD_2[3].Count);
546
547 std::unique_ptr<InstrProfValueData[]> VD_3(
David Blaikiefed557e2016-02-09 01:02:24 +0000548 R->getValueForSite(IPVK_IndirectCallTarget, 3));
Xinliang David Li2004f002015-11-02 05:08:23 +0000549 ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee1"));
550 ASSERT_EQ(1U, VD_3[0].Count);
551
552 std::unique_ptr<InstrProfValueData[]> VD_4(
David Blaikiefed557e2016-02-09 01:02:24 +0000553 R->getValueForSite(IPVK_IndirectCallTarget, 4));
Xinliang David Li2004f002015-11-02 05:08:23 +0000554 ASSERT_EQ(StringRef((const char *)VD_4[0].Value, 7), StringRef("callee3"));
555 ASSERT_EQ(6U, VD_4[0].Count);
556 ASSERT_EQ(StringRef((const char *)VD_4[1].Value, 7), StringRef("callee2"));
557 ASSERT_EQ(4U, VD_4[1].Count);
558 ASSERT_EQ(StringRef((const char *)VD_4[2].Value, 7), StringRef("callee1"));
559 ASSERT_EQ(2U, VD_4[2].Count);
560}
561
Vedant Kumar00dab222016-01-29 22:54:45 +0000562TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge1_saturation) {
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000563 static const char bar[] = "bar";
564
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000565 const uint64_t Max = std::numeric_limits<uint64_t>::max();
566
David Blaikie5b079d82017-07-06 05:19:17 +0000567 auto Result1 = Writer.addRecord({"foo", 0x1234, {1}});
Vedant Kumar9152fd12016-05-19 03:54:45 +0000568 ASSERT_EQ(InstrProfError::take(std::move(Result1)),
569 instrprof_error::success);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000570
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000571 // Verify counter overflow.
David Blaikie5b079d82017-07-06 05:19:17 +0000572 auto Result2 = Writer.addRecord({"foo", 0x1234, {Max}});
Vedant Kumar9152fd12016-05-19 03:54:45 +0000573 ASSERT_EQ(InstrProfError::take(std::move(Result2)),
574 instrprof_error::counter_overflow);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000575
David Blaikie5b079d82017-07-06 05:19:17 +0000576 auto Result3 = Writer.addRecord({bar, 0x9012, {8}});
Vedant Kumar9152fd12016-05-19 03:54:45 +0000577 ASSERT_EQ(InstrProfError::take(std::move(Result3)),
578 instrprof_error::success);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000579
David Blaikiecf9d52c2017-07-06 19:00:12 +0000580 NamedInstrProfRecord Record4("baz", 0x5678, {3, 4});
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000581 Record4.reserveSites(IPVK_IndirectCallTarget, 1);
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000582 InstrProfValueData VD4[] = {{uint64_t(bar), 1}};
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000583 Record4.addValueData(IPVK_IndirectCallTarget, 0, VD4, 1, nullptr);
584 auto Result4 = Writer.addRecord(std::move(Record4));
Vedant Kumar9152fd12016-05-19 03:54:45 +0000585 ASSERT_EQ(InstrProfError::take(std::move(Result4)),
586 instrprof_error::success);
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000587
588 // Verify value data counter overflow.
David Blaikiecf9d52c2017-07-06 19:00:12 +0000589 NamedInstrProfRecord Record5("baz", 0x5678, {5, 6});
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000590 Record5.reserveSites(IPVK_IndirectCallTarget, 1);
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000591 InstrProfValueData VD5[] = {{uint64_t(bar), Max}};
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000592 Record5.addValueData(IPVK_IndirectCallTarget, 0, VD5, 1, nullptr);
593 auto Result5 = Writer.addRecord(std::move(Record5));
Vedant Kumar9152fd12016-05-19 03:54:45 +0000594 ASSERT_EQ(InstrProfError::take(std::move(Result5)),
595 instrprof_error::counter_overflow);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000596
597 auto Profile = Writer.writeBuffer();
598 readProfile(std::move(Profile));
599
600 // Verify saturation of counts.
Vedant Kumar9152fd12016-05-19 03:54:45 +0000601 Expected<InstrProfRecord> ReadRecord1 =
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000602 Reader->getInstrProfRecord("foo", 0x1234);
Vedant Kumar9152fd12016-05-19 03:54:45 +0000603 ASSERT_TRUE(NoError(ReadRecord1.takeError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000604 ASSERT_EQ(Max, ReadRecord1->Counts[0]);
Nathan Slingerlandaa5702d2015-12-02 18:19:24 +0000605
Vedant Kumar9152fd12016-05-19 03:54:45 +0000606 Expected<InstrProfRecord> ReadRecord2 =
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000607 Reader->getInstrProfRecord("baz", 0x5678);
Vedant Kumar9152fd12016-05-19 03:54:45 +0000608 ASSERT_TRUE(bool(ReadRecord2));
David Blaikiefed557e2016-02-09 01:02:24 +0000609 ASSERT_EQ(1U, ReadRecord2->getNumValueSites(IPVK_IndirectCallTarget));
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000610 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000611 ReadRecord2->getValueForSite(IPVK_IndirectCallTarget, 0);
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000612 ASSERT_EQ(StringRef("bar"), StringRef((const char *)VD[0].Value, 3));
613 ASSERT_EQ(Max, VD[0].Count);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000614}
615
Xinliang David Li872df222016-01-08 06:54:27 +0000616// This test tests that when there are too many values
617// for a given site, the merged results are properly
618// truncated.
Vedant Kumar00dab222016-01-29 22:54:45 +0000619TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge_site_trunc) {
Xinliang David Li872df222016-01-08 06:54:27 +0000620 static const char caller[] = "caller";
621
David Blaikiecf9d52c2017-07-06 19:00:12 +0000622 NamedInstrProfRecord Record11(caller, 0x1234, {1, 2});
623 NamedInstrProfRecord Record12(caller, 0x1234, {1, 2});
Xinliang David Li872df222016-01-08 06:54:27 +0000624
625 // 2 value sites.
626 Record11.reserveSites(IPVK_IndirectCallTarget, 2);
627 InstrProfValueData VD0[255];
628 for (int I = 0; I < 255; I++) {
629 VD0[I].Value = 2 * I;
630 VD0[I].Count = 2 * I + 1000;
631 }
632
633 Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 255, nullptr);
634 Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
635
636 Record12.reserveSites(IPVK_IndirectCallTarget, 2);
637 InstrProfValueData VD1[255];
638 for (int I = 0; I < 255; I++) {
639 VD1[I].Value = 2 * I + 1;
640 VD1[I].Count = 2 * I + 1001;
641 }
642
643 Record12.addValueData(IPVK_IndirectCallTarget, 0, VD1, 255, nullptr);
644 Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
645
Vedant Kumarec210812016-05-03 17:07:06 +0000646 NoError(Writer.addRecord(std::move(Record11)));
Xinliang David Li872df222016-01-08 06:54:27 +0000647 // Merge profile data.
Vedant Kumarec210812016-05-03 17:07:06 +0000648 NoError(Writer.addRecord(std::move(Record12)));
Xinliang David Li872df222016-01-08 06:54:27 +0000649
650 auto Profile = Writer.writeBuffer();
651 readProfile(std::move(Profile));
652
Vedant Kumar9152fd12016-05-19 03:54:45 +0000653 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
654 ASSERT_TRUE(NoError(R.takeError()));
Xinliang David Li872df222016-01-08 06:54:27 +0000655 std::unique_ptr<InstrProfValueData[]> VD(
David Blaikiefed557e2016-02-09 01:02:24 +0000656 R->getValueForSite(IPVK_IndirectCallTarget, 0));
657 ASSERT_EQ(2U, R->getNumValueSites(IPVK_IndirectCallTarget));
658 ASSERT_EQ(255U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
NAKAMURA Takumi249edf32016-01-08 07:58:20 +0000659 for (unsigned I = 0; I < 255; I++) {
Xinliang David Li872df222016-01-08 06:54:27 +0000660 ASSERT_EQ(VD[I].Value, 509 - I);
661 ASSERT_EQ(VD[I].Count, 1509 - I);
662 }
663}
664
Xinliang David Li8e6b9172016-05-13 00:23:49 +0000665static void addValueProfData(InstrProfRecord &Record) {
666 Record.reserveSites(IPVK_IndirectCallTarget, 5);
667 InstrProfValueData VD0[] = {{uint64_t(callee1), 400},
668 {uint64_t(callee2), 1000},
669 {uint64_t(callee3), 500},
670 {uint64_t(callee4), 300},
671 {uint64_t(callee5), 100}};
672 Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 5, nullptr);
673 InstrProfValueData VD1[] = {{uint64_t(callee5), 800},
674 {uint64_t(callee3), 1000},
675 {uint64_t(callee2), 2500},
676 {uint64_t(callee1), 1300}};
677 Record.addValueData(IPVK_IndirectCallTarget, 1, VD1, 4, nullptr);
678 InstrProfValueData VD2[] = {{uint64_t(callee6), 800},
679 {uint64_t(callee3), 1000},
680 {uint64_t(callee4), 5500}};
681 Record.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr);
682 InstrProfValueData VD3[] = {{uint64_t(callee2), 1800},
683 {uint64_t(callee3), 2000}};
684 Record.addValueData(IPVK_IndirectCallTarget, 3, VD3, 2, nullptr);
685 Record.addValueData(IPVK_IndirectCallTarget, 4, nullptr, 0, nullptr);
686}
Xinliang David Lied966772015-11-25 23:31:18 +0000687
Xinliang David Li8e6b9172016-05-13 00:23:49 +0000688TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write) {
David Blaikiecf9d52c2017-07-06 19:00:12 +0000689 InstrProfRecord SrcRecord({1ULL << 31, 2});
Xinliang David Li8e6b9172016-05-13 00:23:49 +0000690 addValueProfData(SrcRecord);
691 std::unique_ptr<ValueProfData> VPData =
692 ValueProfData::serializeFrom(SrcRecord);
Xinliang David Lied966772015-11-25 23:31:18 +0000693
David Blaikiecf9d52c2017-07-06 19:00:12 +0000694 InstrProfRecord Record({1ULL << 31, 2});
Eugene Zelenko6ac3f732016-01-26 18:48:36 +0000695 VPData->deserializeTo(Record, nullptr);
Xinliang David Lied966772015-11-25 23:31:18 +0000696
697 // Now read data from Record and sanity check the data
698 ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget));
699 ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
700 ASSERT_EQ(4U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
701 ASSERT_EQ(3U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
702 ASSERT_EQ(2U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
703 ASSERT_EQ(0U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 4));
704
705 auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
706 return VD1.Count > VD2.Count;
707 };
708 std::unique_ptr<InstrProfValueData[]> VD_0(
709 Record.getValueForSite(IPVK_IndirectCallTarget, 0));
710 std::sort(&VD_0[0], &VD_0[5], Cmp);
711 ASSERT_EQ(StringRef((const char *)VD_0[0].Value, 7), StringRef("callee2"));
712 ASSERT_EQ(1000U, VD_0[0].Count);
713 ASSERT_EQ(StringRef((const char *)VD_0[1].Value, 7), StringRef("callee3"));
714 ASSERT_EQ(500U, VD_0[1].Count);
715 ASSERT_EQ(StringRef((const char *)VD_0[2].Value, 7), StringRef("callee1"));
716 ASSERT_EQ(400U, VD_0[2].Count);
717 ASSERT_EQ(StringRef((const char *)VD_0[3].Value, 7), StringRef("callee4"));
718 ASSERT_EQ(300U, VD_0[3].Count);
719 ASSERT_EQ(StringRef((const char *)VD_0[4].Value, 7), StringRef("callee5"));
720 ASSERT_EQ(100U, VD_0[4].Count);
721
722 std::unique_ptr<InstrProfValueData[]> VD_1(
723 Record.getValueForSite(IPVK_IndirectCallTarget, 1));
724 std::sort(&VD_1[0], &VD_1[4], Cmp);
725 ASSERT_EQ(StringRef((const char *)VD_1[0].Value, 7), StringRef("callee2"));
726 ASSERT_EQ(2500U, VD_1[0].Count);
727 ASSERT_EQ(StringRef((const char *)VD_1[1].Value, 7), StringRef("callee1"));
728 ASSERT_EQ(1300U, VD_1[1].Count);
729 ASSERT_EQ(StringRef((const char *)VD_1[2].Value, 7), StringRef("callee3"));
730 ASSERT_EQ(1000U, VD_1[2].Count);
731 ASSERT_EQ(StringRef((const char *)VD_1[3].Value, 7), StringRef("callee5"));
732 ASSERT_EQ(800U, VD_1[3].Count);
733
734 std::unique_ptr<InstrProfValueData[]> VD_2(
735 Record.getValueForSite(IPVK_IndirectCallTarget, 2));
736 std::sort(&VD_2[0], &VD_2[3], Cmp);
737 ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee4"));
738 ASSERT_EQ(5500U, VD_2[0].Count);
739 ASSERT_EQ(StringRef((const char *)VD_2[1].Value, 7), StringRef("callee3"));
740 ASSERT_EQ(1000U, VD_2[1].Count);
741 ASSERT_EQ(StringRef((const char *)VD_2[2].Value, 7), StringRef("callee6"));
742 ASSERT_EQ(800U, VD_2[2].Count);
743
744 std::unique_ptr<InstrProfValueData[]> VD_3(
745 Record.getValueForSite(IPVK_IndirectCallTarget, 3));
746 std::sort(&VD_3[0], &VD_3[2], Cmp);
747 ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee3"));
748 ASSERT_EQ(2000U, VD_3[0].Count);
749 ASSERT_EQ(StringRef((const char *)VD_3[1].Value, 7), StringRef("callee2"));
750 ASSERT_EQ(1800U, VD_3[1].Count);
Xinliang David Lied966772015-11-25 23:31:18 +0000751}
752
Xinliang David Li8e6b9172016-05-13 00:23:49 +0000753TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write_mapping) {
Xinliang David Li28464482016-04-10 03:32:02 +0000754
David Blaikiecf9d52c2017-07-06 19:00:12 +0000755 NamedInstrProfRecord SrcRecord("caller", 0x1234, {1ULL << 31, 2});
Xinliang David Li8e6b9172016-05-13 00:23:49 +0000756 addValueProfData(SrcRecord);
757 std::unique_ptr<ValueProfData> VPData =
758 ValueProfData::serializeFrom(SrcRecord);
Xinliang David Li28464482016-04-10 03:32:02 +0000759
David Blaikiecf9d52c2017-07-06 19:00:12 +0000760 NamedInstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2});
Xinliang David Li28464482016-04-10 03:32:02 +0000761 InstrProfSymtab Symtab;
762 Symtab.mapAddress(uint64_t(callee1), 0x1000ULL);
763 Symtab.mapAddress(uint64_t(callee2), 0x2000ULL);
764 Symtab.mapAddress(uint64_t(callee3), 0x3000ULL);
765 Symtab.mapAddress(uint64_t(callee4), 0x4000ULL);
766 // Missing mapping for callee5
767 Symtab.finalizeSymtab();
768
769 VPData->deserializeTo(Record, &Symtab.getAddrHashMap());
770
771 // Now read data from Record and sanity check the data
Xinliang David Li8e6b9172016-05-13 00:23:49 +0000772 ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget));
Xinliang David Li28464482016-04-10 03:32:02 +0000773 ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
774
775 auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
776 return VD1.Count > VD2.Count;
777 };
778 std::unique_ptr<InstrProfValueData[]> VD_0(
779 Record.getValueForSite(IPVK_IndirectCallTarget, 0));
780 std::sort(&VD_0[0], &VD_0[5], Cmp);
781 ASSERT_EQ(VD_0[0].Value, 0x2000ULL);
782 ASSERT_EQ(1000U, VD_0[0].Count);
783 ASSERT_EQ(VD_0[1].Value, 0x3000ULL);
784 ASSERT_EQ(500U, VD_0[1].Count);
785 ASSERT_EQ(VD_0[2].Value, 0x1000ULL);
786 ASSERT_EQ(400U, VD_0[2].Count);
787
788 // callee5 does not have a mapped value -- default to 0.
789 ASSERT_EQ(VD_0[4].Value, 0ULL);
790}
791
Vedant Kumar00dab222016-01-29 22:54:45 +0000792TEST_P(MaybeSparseInstrProfTest, get_max_function_count) {
David Blaikie5b079d82017-07-06 05:19:17 +0000793 NoError(Writer.addRecord({"foo", 0x1234, {1ULL << 31, 2}}));
794 NoError(Writer.addRecord({"bar", 0, {1ULL << 63}}));
795 NoError(Writer.addRecord({"baz", 0x5678, {0, 0, 0, 0}}));
Justin Bogner2b6c5372015-02-18 01:58:17 +0000796 auto Profile = Writer.writeBuffer();
797 readProfile(std::move(Profile));
798
799 ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount());
800}
801
Vedant Kumar00dab222016-01-29 22:54:45 +0000802TEST_P(MaybeSparseInstrProfTest, get_weighted_function_counts) {
David Blaikie5b079d82017-07-06 05:19:17 +0000803 NoError(Writer.addRecord({"foo", 0x1234, {1, 2}}, 3));
804 NoError(Writer.addRecord({"foo", 0x1235, {3, 4}}, 5));
Nathan Slingerland7f5b47d2015-12-15 17:37:09 +0000805 auto Profile = Writer.writeBuffer();
806 readProfile(std::move(Profile));
807
808 std::vector<uint64_t> Counts;
809 ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1234, Counts)));
810 ASSERT_EQ(2U, Counts.size());
811 ASSERT_EQ(3U, Counts[0]);
812 ASSERT_EQ(6U, Counts[1]);
813
814 ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1235, Counts)));
815 ASSERT_EQ(2U, Counts.size());
816 ASSERT_EQ(15U, Counts[0]);
817 ASSERT_EQ(20U, Counts[1]);
818}
819
Xinliang David Lia0601e72016-02-09 05:47:08 +0000820// Testing symtab creator interface used by indexed profile reader.
Vedant Kumar00dab222016-01-29 22:54:45 +0000821TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_test) {
Xinliang David Li2ee5c4d2015-12-19 07:44:57 +0000822 std::vector<StringRef> FuncNames;
823 FuncNames.push_back("func1");
824 FuncNames.push_back("func2");
825 FuncNames.push_back("func3");
826 FuncNames.push_back("bar1");
827 FuncNames.push_back("bar2");
828 FuncNames.push_back("bar3");
829 InstrProfSymtab Symtab;
Vedant Kumarb5794ca2017-06-20 01:38:56 +0000830 NoError(Symtab.create(FuncNames));
Xinliang David Li2ee5c4d2015-12-19 07:44:57 +0000831 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
832 ASSERT_EQ(StringRef("func1"), R);
833 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
834 ASSERT_EQ(StringRef("func2"), R);
835 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
836 ASSERT_EQ(StringRef("func3"), R);
837 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
838 ASSERT_EQ(StringRef("bar1"), R);
839 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
840 ASSERT_EQ(StringRef("bar2"), R);
841 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
842 ASSERT_EQ(StringRef("bar3"), R);
Xinliang David Lic96d3d12015-12-19 18:20:09 +0000843
Xinliang David Li86b4b912016-02-10 06:36:55 +0000844 // negative tests
845 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar4"));
846 ASSERT_EQ(StringRef(), R);
847 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("foo4"));
848 ASSERT_EQ(StringRef(), R);
849
Xinliang David Lic96d3d12015-12-19 18:20:09 +0000850 // Now incrementally update the symtab
Vedant Kumarb5794ca2017-06-20 01:38:56 +0000851 NoError(Symtab.addFuncName("blah_1"));
852 NoError(Symtab.addFuncName("blah_2"));
853 NoError(Symtab.addFuncName("blah_3"));
Xinliang David Lic96d3d12015-12-19 18:20:09 +0000854 // Finalize it
855 Symtab.finalizeSymtab();
856
857 // Check again
858 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_1"));
859 ASSERT_EQ(StringRef("blah_1"), R);
860 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_2"));
861 ASSERT_EQ(StringRef("blah_2"), R);
862 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_3"));
863 ASSERT_EQ(StringRef("blah_3"), R);
864 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
865 ASSERT_EQ(StringRef("func1"), R);
866 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
867 ASSERT_EQ(StringRef("func2"), R);
868 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
869 ASSERT_EQ(StringRef("func3"), R);
870 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
871 ASSERT_EQ(StringRef("bar1"), R);
872 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
873 ASSERT_EQ(StringRef("bar2"), R);
874 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
875 ASSERT_EQ(StringRef("bar3"), R);
Xinliang David Li2ee5c4d2015-12-19 07:44:57 +0000876}
877
Vedant Kumarb5794ca2017-06-20 01:38:56 +0000878// Test that we get an error when creating a bogus symtab.
879TEST_P(MaybeSparseInstrProfTest, instr_prof_bogus_symtab_empty_func_name) {
880 InstrProfSymtab Symtab;
881 ErrorEquals(instrprof_error::malformed, Symtab.addFuncName(""));
882}
883
Xinliang David Lia0601e72016-02-09 05:47:08 +0000884// Testing symtab creator interface used by value profile transformer.
Vedant Kumar00dab222016-01-29 22:54:45 +0000885TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_module_test) {
Xinliang David Li59411db2016-01-20 01:26:34 +0000886 LLVMContext Ctx;
887 std::unique_ptr<Module> M = llvm::make_unique<Module>("MyModule.cpp", Ctx);
888 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
889 /*isVarArg=*/false);
890 Function::Create(FTy, Function::ExternalLinkage, "Gfoo", M.get());
891 Function::Create(FTy, Function::ExternalLinkage, "Gblah", M.get());
892 Function::Create(FTy, Function::ExternalLinkage, "Gbar", M.get());
893 Function::Create(FTy, Function::InternalLinkage, "Ifoo", M.get());
894 Function::Create(FTy, Function::InternalLinkage, "Iblah", M.get());
895 Function::Create(FTy, Function::InternalLinkage, "Ibar", M.get());
896 Function::Create(FTy, Function::PrivateLinkage, "Pfoo", M.get());
897 Function::Create(FTy, Function::PrivateLinkage, "Pblah", M.get());
898 Function::Create(FTy, Function::PrivateLinkage, "Pbar", M.get());
899 Function::Create(FTy, Function::WeakODRLinkage, "Wfoo", M.get());
900 Function::Create(FTy, Function::WeakODRLinkage, "Wblah", M.get());
901 Function::Create(FTy, Function::WeakODRLinkage, "Wbar", M.get());
902
903 InstrProfSymtab ProfSymtab;
Vedant Kumarb5794ca2017-06-20 01:38:56 +0000904 NoError(ProfSymtab.create(*M));
Xinliang David Li59411db2016-01-20 01:26:34 +0000905
906 StringRef Funcs[] = {"Gfoo", "Gblah", "Gbar", "Ifoo", "Iblah", "Ibar",
907 "Pfoo", "Pblah", "Pbar", "Wfoo", "Wblah", "Wbar"};
908
909 for (unsigned I = 0; I < sizeof(Funcs) / sizeof(*Funcs); I++) {
910 Function *F = M->getFunction(Funcs[I]);
Eugene Zelenko6ac3f732016-01-26 18:48:36 +0000911 ASSERT_TRUE(F != nullptr);
Xinliang David Lida656fe2016-01-20 02:49:53 +0000912 std::string PGOName = getPGOFuncName(*F);
Xinliang David Li3865fdc2016-01-22 18:13:34 +0000913 uint64_t Key = IndexedInstrProf::ComputeHash(PGOName);
Xinliang David Lida656fe2016-01-20 02:49:53 +0000914 ASSERT_EQ(StringRef(PGOName),
Xinliang David Li3865fdc2016-01-22 18:13:34 +0000915 ProfSymtab.getFuncName(Key));
916 ASSERT_EQ(StringRef(Funcs[I]), ProfSymtab.getOrigFuncName(Key));
Xinliang David Li59411db2016-01-20 01:26:34 +0000917 }
918}
919
Xinliang David Lia0601e72016-02-09 05:47:08 +0000920// Testing symtab serialization and creator/deserialization interface
921// used by coverage map reader, and raw profile reader.
Vedant Kumar00dab222016-01-29 22:54:45 +0000922TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_compression_test) {
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000923 std::vector<std::string> FuncNames1;
924 std::vector<std::string> FuncNames2;
Xinliang David Lic2f25cc42016-02-09 05:36:57 +0000925 for (int I = 0; I < 3; I++) {
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000926 std::string str;
927 raw_string_ostream OS(str);
928 OS << "func_" << I;
929 FuncNames1.push_back(OS.str());
930 str.clear();
Vedant Kumar86705ba2016-03-28 21:06:42 +0000931 OS << "f oooooooooooooo_" << I;
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000932 FuncNames1.push_back(OS.str());
933 str.clear();
934 OS << "BAR_" << I;
935 FuncNames2.push_back(OS.str());
936 str.clear();
937 OS << "BlahblahBlahblahBar_" << I;
938 FuncNames2.push_back(OS.str());
939 }
940
Xinliang David Lidd4ae7b2016-01-29 22:29:15 +0000941 for (bool DoCompression : {false, true}) {
942 // Compressing:
943 std::string FuncNameStrings1;
Vedant Kumarec210812016-05-03 17:07:06 +0000944 NoError(collectPGOFuncNameStrings(
945 FuncNames1, (DoCompression && zlib::isAvailable()), FuncNameStrings1));
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000946
Xinliang David Lidd4ae7b2016-01-29 22:29:15 +0000947 // Compressing:
948 std::string FuncNameStrings2;
Vedant Kumarec210812016-05-03 17:07:06 +0000949 NoError(collectPGOFuncNameStrings(
950 FuncNames2, (DoCompression && zlib::isAvailable()), FuncNameStrings2));
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000951
Xinliang David Lic2f25cc42016-02-09 05:36:57 +0000952 for (int Padding = 0; Padding < 2; Padding++) {
953 // Join with paddings :
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000954 std::string FuncNameStrings = FuncNameStrings1;
955 for (int P = 0; P < Padding; P++) {
956 FuncNameStrings.push_back('\0');
957 }
958 FuncNameStrings += FuncNameStrings2;
959
Xinliang David Li8dec8b12016-01-04 23:59:14 +0000960 // Now decompress:
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000961 InstrProfSymtab Symtab;
Vedant Kumarec210812016-05-03 17:07:06 +0000962 NoError(Symtab.create(StringRef(FuncNameStrings)));
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000963
Xinliang David Li8dec8b12016-01-04 23:59:14 +0000964 // Now do the checks:
965 // First sampling some data points:
Xinliang David Lia8ba7af2016-01-29 21:26:31 +0000966 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[0]));
Xinliang David Li8dec8b12016-01-04 23:59:14 +0000967 ASSERT_EQ(StringRef("func_0"), R);
968 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[1]));
Vedant Kumar86705ba2016-03-28 21:06:42 +0000969 ASSERT_EQ(StringRef("f oooooooooooooo_0"), R);
Xinliang David Lic2f25cc42016-02-09 05:36:57 +0000970 for (int I = 0; I < 3; I++) {
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000971 std::string N[4];
972 N[0] = FuncNames1[2 * I];
973 N[1] = FuncNames1[2 * I + 1];
974 N[2] = FuncNames2[2 * I];
975 N[3] = FuncNames2[2 * I + 1];
976 for (int J = 0; J < 4; J++) {
977 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(N[J]));
978 ASSERT_EQ(StringRef(N[J]), R);
979 }
980 }
981 }
982 }
983}
984
Vedant Kumar00dab222016-01-29 22:54:45 +0000985TEST_F(SparseInstrProfTest, preserve_no_records) {
David Blaikie5b079d82017-07-06 05:19:17 +0000986 NoError(Writer.addRecord({"foo", 0x1234, {0}}));
987 NoError(Writer.addRecord({"bar", 0x4321, {0, 0}}));
988 NoError(Writer.addRecord({"bar", 0x4321, {0, 0, 0}}));
Vedant Kumar00dab222016-01-29 22:54:45 +0000989
Vedant Kumar00dab222016-01-29 22:54:45 +0000990 auto Profile = Writer.writeBuffer();
991 readProfile(std::move(Profile));
992
993 auto I = Reader->begin(), E = Reader->end();
994 ASSERT_TRUE(I == E);
995}
996
997INSTANTIATE_TEST_CASE_P(MaybeSparse, MaybeSparseInstrProfTest,
Galina Kistanova94177352017-06-04 05:30:26 +0000998 ::testing::Bool(),);
Vedant Kumar00dab222016-01-29 22:54:45 +0000999
Justin Bogner2b6c5372015-02-18 01:58:17 +00001000} // end anonymous namespace