blob: 8659a8fd782ff8f009b102bf21ca8e23a7626983 [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
22static ::testing::AssertionResult NoError(std::error_code EC) {
23 if (!EC)
24 return ::testing::AssertionSuccess();
25 return ::testing::AssertionFailure() << "error " << EC.value()
26 << ": " << EC.message();
27}
28
29static ::testing::AssertionResult ErrorEquals(std::error_code Expected,
30 std::error_code Found) {
31 if (Expected == Found)
32 return ::testing::AssertionSuccess();
33 return ::testing::AssertionFailure() << "error " << Found.value()
34 << ": " << Found.message();
35}
36
37namespace {
38
39struct InstrProfTest : ::testing::Test {
40 InstrProfWriter Writer;
41 std::unique_ptr<IndexedInstrProfReader> Reader;
42
Vedant Kumar00dab222016-01-29 22:54:45 +000043 void SetUp() { Writer.setOutputSparse(false); }
44
Justin Bogner2b6c5372015-02-18 01:58:17 +000045 void readProfile(std::unique_ptr<MemoryBuffer> Profile) {
46 auto ReaderOrErr = IndexedInstrProfReader::create(std::move(Profile));
47 ASSERT_TRUE(NoError(ReaderOrErr.getError()));
48 Reader = std::move(ReaderOrErr.get());
49 }
50};
51
Vedant Kumar00dab222016-01-29 22:54:45 +000052struct SparseInstrProfTest : public InstrProfTest {
53 void SetUp() { Writer.setOutputSparse(true); }
54};
55
56struct MaybeSparseInstrProfTest : public InstrProfTest,
57 public ::testing::WithParamInterface<bool> {
Vedant Kumar0259b7b2016-03-22 15:14:18 +000058 void SetUp() { Writer.setOutputSparse(GetParam()); }
Vedant Kumar00dab222016-01-29 22:54:45 +000059};
60
61TEST_P(MaybeSparseInstrProfTest, write_and_read_empty_profile) {
Justin Bogner2b6c5372015-02-18 01:58:17 +000062 auto Profile = Writer.writeBuffer();
63 readProfile(std::move(Profile));
64 ASSERT_TRUE(Reader->begin() == Reader->end());
65}
66
Vedant Kumar00dab222016-01-29 22:54:45 +000067TEST_P(MaybeSparseInstrProfTest, write_and_read_one_function) {
Justin Bogner9e9a0572015-09-29 22:13:58 +000068 InstrProfRecord Record("foo", 0x1234, {1, 2, 3, 4});
Vedant Kumarec210812016-05-03 17:07:06 +000069 NoError(Writer.addRecord(std::move(Record)));
Justin Bogner2b6c5372015-02-18 01:58:17 +000070 auto Profile = Writer.writeBuffer();
71 readProfile(std::move(Profile));
72
73 auto I = Reader->begin(), E = Reader->end();
74 ASSERT_TRUE(I != E);
75 ASSERT_EQ(StringRef("foo"), I->Name);
76 ASSERT_EQ(0x1234U, I->Hash);
77 ASSERT_EQ(4U, I->Counts.size());
78 ASSERT_EQ(1U, I->Counts[0]);
79 ASSERT_EQ(2U, I->Counts[1]);
80 ASSERT_EQ(3U, I->Counts[2]);
81 ASSERT_EQ(4U, I->Counts[3]);
82 ASSERT_TRUE(++I == E);
83}
84
Vedant Kumar00dab222016-01-29 22:54:45 +000085TEST_P(MaybeSparseInstrProfTest, get_instr_prof_record) {
Xinliang David Li2004f002015-11-02 05:08:23 +000086 InstrProfRecord Record1("foo", 0x1234, {1, 2});
87 InstrProfRecord Record2("foo", 0x1235, {3, 4});
Vedant Kumarec210812016-05-03 17:07:06 +000088 NoError(Writer.addRecord(std::move(Record1)));
89 NoError(Writer.addRecord(std::move(Record2)));
Xinliang David Li2004f002015-11-02 05:08:23 +000090 auto Profile = Writer.writeBuffer();
91 readProfile(std::move(Profile));
92
93 ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("foo", 0x1234);
94 ASSERT_TRUE(NoError(R.getError()));
David Blaikiefed557e2016-02-09 01:02:24 +000095 ASSERT_EQ(2U, R->Counts.size());
96 ASSERT_EQ(1U, R->Counts[0]);
97 ASSERT_EQ(2U, R->Counts[1]);
Xinliang David Li2004f002015-11-02 05:08:23 +000098
99 R = Reader->getInstrProfRecord("foo", 0x1235);
100 ASSERT_TRUE(NoError(R.getError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000101 ASSERT_EQ(2U, R->Counts.size());
102 ASSERT_EQ(3U, R->Counts[0]);
103 ASSERT_EQ(4U, R->Counts[1]);
Xinliang David Li2004f002015-11-02 05:08:23 +0000104
105 R = Reader->getInstrProfRecord("foo", 0x5678);
106 ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, R.getError()));
107
108 R = Reader->getInstrProfRecord("bar", 0x1234);
109 ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, R.getError()));
110}
111
Vedant Kumar00dab222016-01-29 22:54:45 +0000112TEST_P(MaybeSparseInstrProfTest, get_function_counts) {
Justin Bogner9e9a0572015-09-29 22:13:58 +0000113 InstrProfRecord Record1("foo", 0x1234, {1, 2});
114 InstrProfRecord Record2("foo", 0x1235, {3, 4});
Vedant Kumarec210812016-05-03 17:07:06 +0000115 NoError(Writer.addRecord(std::move(Record1)));
116 NoError(Writer.addRecord(std::move(Record2)));
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
Justin Bogner2b6c5372015-02-18 01:58:17 +0000131 std::error_code EC;
132 EC = Reader->getFunctionCounts("foo", 0x5678, Counts);
133 ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, EC));
134
135 EC = Reader->getFunctionCounts("bar", 0x1234, Counts);
136 ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, EC));
137}
138
Xinliang David Li6c93ee82016-02-03 04:08:18 +0000139// Profile data is copied from general.proftext
140TEST_F(InstrProfTest, get_profile_summary) {
141 InstrProfRecord Record1("func1", 0x1234, {97531});
142 InstrProfRecord Record2("func2", 0x1234, {0, 0});
143 InstrProfRecord Record3("func3", 0x1234,
144 {2305843009213693952, 1152921504606846976,
145 576460752303423488, 288230376151711744,
146 144115188075855872, 72057594037927936});
147 InstrProfRecord Record4("func4", 0x1234, {0});
Vedant Kumarec210812016-05-03 17:07:06 +0000148 NoError(Writer.addRecord(std::move(Record1)));
149 NoError(Writer.addRecord(std::move(Record2)));
150 NoError(Writer.addRecord(std::move(Record3)));
151 NoError(Writer.addRecord(std::move(Record4)));
Xinliang David Li6c93ee82016-02-03 04:08:18 +0000152 auto Profile = Writer.writeBuffer();
153 readProfile(std::move(Profile));
154
Easwaran Ramanf9709ee2016-03-14 22:23:28 +0000155 auto VerifySummary = [](InstrProfSummary &IPS) mutable {
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000156 ASSERT_EQ(2305843009213693952U, IPS.getMaxFunctionCount());
157 ASSERT_EQ(2305843009213693952U, IPS.getMaxBlockCount());
158 ASSERT_EQ(10U, IPS.getNumBlocks());
159 ASSERT_EQ(4539628424389557499U, IPS.getTotalCount());
160 std::vector<ProfileSummaryEntry> &Details = IPS.getDetailedSummary();
161 uint32_t Cutoff = 800000;
162 auto Predicate = [&Cutoff](const ProfileSummaryEntry &PE) {
163 return PE.Cutoff == Cutoff;
164 };
165 auto EightyPerc = std::find_if(Details.begin(), Details.end(), Predicate);
166 Cutoff = 900000;
167 auto NinetyPerc = std::find_if(Details.begin(), Details.end(), Predicate);
168 Cutoff = 950000;
169 auto NinetyFivePerc =
170 std::find_if(Details.begin(), Details.end(), Predicate);
171 Cutoff = 990000;
172 auto NinetyNinePerc =
173 std::find_if(Details.begin(), Details.end(), Predicate);
174 ASSERT_EQ(576460752303423488U, EightyPerc->MinCount);
175 ASSERT_EQ(288230376151711744U, NinetyPerc->MinCount);
176 ASSERT_EQ(288230376151711744U, NinetyFivePerc->MinCount);
177 ASSERT_EQ(72057594037927936U, NinetyNinePerc->MinCount);
Xinliang David Li6c93ee82016-02-03 04:08:18 +0000178 };
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000179 InstrProfSummary &PS = Reader->getSummary();
Easwaran Ramanf9709ee2016-03-14 22:23:28 +0000180 VerifySummary(PS);
Easwaran Raman26628d32016-03-18 21:29:30 +0000181
182 // Test that conversion of summary to and from Metadata works.
Mehdi Amini03b42e42016-04-14 21:59:01 +0000183 LLVMContext Context;
184 Metadata *MD = PS.getMD(Context);
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000185 ASSERT_TRUE(MD);
186 ProfileSummary *PSFromMD = ProfileSummary::getFromMD(MD);
187 ASSERT_TRUE(PSFromMD);
188 ASSERT_TRUE(isa<InstrProfSummary>(PSFromMD));
189 InstrProfSummary *IPS = cast<InstrProfSummary>(PSFromMD);
Easwaran Ramanf9709ee2016-03-14 22:23:28 +0000190 VerifySummary(*IPS);
Easwaran Raman75c21a92016-03-03 23:55:41 +0000191 delete IPS;
Easwaran Raman26628d32016-03-18 21:29:30 +0000192
193 // Test that summary can be attached to and read back from module.
Mehdi Amini03b42e42016-04-14 21:59:01 +0000194 Module M("my_module", Context);
Easwaran Raman26628d32016-03-18 21:29:30 +0000195 M.setProfileSummary(MD);
196 MD = M.getProfileSummary();
197 ASSERT_TRUE(MD);
198 PSFromMD = ProfileSummary::getFromMD(MD);
199 ASSERT_TRUE(PSFromMD);
200 ASSERT_TRUE(isa<InstrProfSummary>(PSFromMD));
201 IPS = cast<InstrProfSummary>(PSFromMD);
202 VerifySummary(*IPS);
203 delete IPS;
Xinliang David Li6c93ee82016-02-03 04:08:18 +0000204}
205
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000206static const char callee1[] = "callee1";
207static const char callee2[] = "callee2";
208static const char callee3[] = "callee3";
209static const char callee4[] = "callee4";
210static const char callee5[] = "callee5";
211static const char callee6[] = "callee6";
212
Vedant Kumar00dab222016-01-29 22:54:45 +0000213TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write) {
Xinliang David Li2004f002015-11-02 05:08:23 +0000214 InstrProfRecord Record1("caller", 0x1234, {1, 2});
215 InstrProfRecord Record2("callee1", 0x1235, {3, 4});
216 InstrProfRecord Record3("callee2", 0x1235, {3, 4});
217 InstrProfRecord Record4("callee3", 0x1235, {3, 4});
218
219 // 4 value sites.
220 Record1.reserveSites(IPVK_IndirectCallTarget, 4);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000221 InstrProfValueData VD0[] = {
222 {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000223 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
Xinliang David Liee415892015-11-10 00:24:45 +0000224 // No value profile data at the second site.
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000225 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000226 InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000227 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000228 InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000229 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000230
Vedant Kumarec210812016-05-03 17:07:06 +0000231 NoError(Writer.addRecord(std::move(Record1)));
232 NoError(Writer.addRecord(std::move(Record2)));
233 NoError(Writer.addRecord(std::move(Record3)));
234 NoError(Writer.addRecord(std::move(Record4)));
Xinliang David Li2004f002015-11-02 05:08:23 +0000235 auto Profile = Writer.writeBuffer();
236 readProfile(std::move(Profile));
237
238 ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
239 ASSERT_TRUE(NoError(R.getError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000240 ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
241 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
242 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
243 ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
244 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
Xinliang David Li2004f002015-11-02 05:08:23 +0000245
Xinliang David Li1e4c8092016-02-04 05:29:51 +0000246 uint64_t TotalC;
Xinliang David Li2004f002015-11-02 05:08:23 +0000247 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000248 R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000249
250 ASSERT_EQ(3U, VD[0].Count);
251 ASSERT_EQ(2U, VD[1].Count);
252 ASSERT_EQ(1U, VD[2].Count);
Xinliang David Li1e4c8092016-02-04 05:29:51 +0000253 ASSERT_EQ(6U, TotalC);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000254
255 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
256 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
257 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
258}
259
Xinliang David Li402477d2016-02-04 19:11:43 +0000260TEST_P(MaybeSparseInstrProfTest, annotate_vp_data) {
261 InstrProfRecord Record("caller", 0x1234, {1, 2});
262 Record.reserveSites(IPVK_IndirectCallTarget, 1);
Rong Xu69683f12016-02-10 22:19:43 +0000263 InstrProfValueData VD0[] = {{1000, 1}, {2000, 2}, {3000, 3}, {5000, 5},
264 {4000, 4}, {6000, 6}};
265 Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 6, nullptr);
Vedant Kumarec210812016-05-03 17:07:06 +0000266 NoError(Writer.addRecord(std::move(Record)));
Xinliang David Li402477d2016-02-04 19:11:43 +0000267 auto Profile = Writer.writeBuffer();
268 readProfile(std::move(Profile));
269 ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
270 ASSERT_TRUE(NoError(R.getError()));
271
272 LLVMContext Ctx;
273 std::unique_ptr<Module> M(new Module("MyModule", Ctx));
274 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
275 /*isVarArg=*/false);
276 Function *F =
277 Function::Create(FTy, Function::ExternalLinkage, "caller", M.get());
278 BasicBlock *BB = BasicBlock::Create(Ctx, "", F);
279
280 IRBuilder<> Builder(BB);
281 BasicBlock *TBB = BasicBlock::Create(Ctx, "", F);
282 BasicBlock *FBB = BasicBlock::Create(Ctx, "", F);
283
284 // Use branch instruction to annotate with value profile data for simplicity
285 Instruction *Inst = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
286 Instruction *Inst2 = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
David Blaikiefed557e2016-02-09 01:02:24 +0000287 annotateValueSite(*M, *Inst, R.get(), IPVK_IndirectCallTarget, 0);
Xinliang David Li402477d2016-02-04 19:11:43 +0000288
289 InstrProfValueData ValueData[5];
290 uint32_t N;
291 uint64_t T;
292 bool Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
293 ValueData, N, T);
294 ASSERT_TRUE(Res);
295 ASSERT_EQ(3U, N);
Rong Xu69683f12016-02-10 22:19:43 +0000296 ASSERT_EQ(21U, T);
Xinliang David Li402477d2016-02-04 19:11:43 +0000297 // The result should be sorted already:
Rong Xu69683f12016-02-10 22:19:43 +0000298 ASSERT_EQ(6000U, ValueData[0].Value);
299 ASSERT_EQ(6U, ValueData[0].Count);
300 ASSERT_EQ(5000U, ValueData[1].Value);
301 ASSERT_EQ(5U, ValueData[1].Count);
302 ASSERT_EQ(4000U, ValueData[2].Value);
303 ASSERT_EQ(4U, ValueData[2].Count);
Xinliang David Li402477d2016-02-04 19:11:43 +0000304 Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 1, ValueData,
305 N, T);
306 ASSERT_TRUE(Res);
307 ASSERT_EQ(1U, N);
Rong Xu69683f12016-02-10 22:19:43 +0000308 ASSERT_EQ(21U, T);
Xinliang David Li402477d2016-02-04 19:11:43 +0000309
310 Res = getValueProfDataFromInst(*Inst2, IPVK_IndirectCallTarget, 5, ValueData,
311 N, T);
312 ASSERT_FALSE(Res);
Rong Xu69683f12016-02-10 22:19:43 +0000313
314 // Remove the MD_prof metadata
315 Inst->setMetadata(LLVMContext::MD_prof, 0);
316 // Annotate 5 records this time.
317 annotateValueSite(*M, *Inst, R.get(), IPVK_IndirectCallTarget, 0, 5);
318 Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
319 ValueData, N, T);
320 ASSERT_TRUE(Res);
321 ASSERT_EQ(5U, N);
322 ASSERT_EQ(21U, T);
323 ASSERT_EQ(6000U, ValueData[0].Value);
324 ASSERT_EQ(6U, ValueData[0].Count);
325 ASSERT_EQ(5000U, ValueData[1].Value);
326 ASSERT_EQ(5U, ValueData[1].Count);
327 ASSERT_EQ(4000U, ValueData[2].Value);
328 ASSERT_EQ(4U, ValueData[2].Count);
329 ASSERT_EQ(3000U, ValueData[3].Value);
330 ASSERT_EQ(3U, ValueData[3].Count);
331 ASSERT_EQ(2000U, ValueData[4].Value);
332 ASSERT_EQ(2U, ValueData[4].Count);
Rong Xubb494902016-02-12 21:36:17 +0000333
334 // Remove the MD_prof metadata
335 Inst->setMetadata(LLVMContext::MD_prof, 0);
336 // Annotate with 4 records.
337 InstrProfValueData VD0Sorted[] = {{1000, 6}, {2000, 5}, {3000, 4}, {4000, 3},
338 {5000, 2}, {6000, 1}};
Rong Xu311ada12016-03-30 16:56:31 +0000339 annotateValueSite(*M, *Inst, makeArrayRef(VD0Sorted).slice(2), 10,
340 IPVK_IndirectCallTarget, 5);
Rong Xubb494902016-02-12 21:36:17 +0000341 Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
342 ValueData, N, T);
343 ASSERT_TRUE(Res);
344 ASSERT_EQ(4U, N);
345 ASSERT_EQ(10U, T);
346 ASSERT_EQ(3000U, ValueData[0].Value);
347 ASSERT_EQ(4U, ValueData[0].Count);
348 ASSERT_EQ(4000U, ValueData[1].Value);
349 ASSERT_EQ(3U, ValueData[1].Count);
350 ASSERT_EQ(5000U, ValueData[2].Value);
351 ASSERT_EQ(2U, ValueData[2].Count);
352 ASSERT_EQ(6000U, ValueData[3].Value);
353 ASSERT_EQ(1U, ValueData[3].Count);
Xinliang David Li402477d2016-02-04 19:11:43 +0000354}
355
Vedant Kumar00dab222016-01-29 22:54:45 +0000356TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_with_weight) {
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000357 InstrProfRecord Record1("caller", 0x1234, {1, 2});
358 InstrProfRecord Record2("callee1", 0x1235, {3, 4});
359 InstrProfRecord Record3("callee2", 0x1235, {3, 4});
360 InstrProfRecord Record4("callee3", 0x1235, {3, 4});
361
362 // 4 value sites.
363 Record1.reserveSites(IPVK_IndirectCallTarget, 4);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000364 InstrProfValueData VD0[] = {
365 {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000366 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
367 // No value profile data at the second site.
368 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000369 InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000370 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000371 InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000372 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
373
Vedant Kumarec210812016-05-03 17:07:06 +0000374 NoError(Writer.addRecord(std::move(Record1), 10));
375 NoError(Writer.addRecord(std::move(Record2)));
376 NoError(Writer.addRecord(std::move(Record3)));
377 NoError(Writer.addRecord(std::move(Record4)));
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000378 auto Profile = Writer.writeBuffer();
379 readProfile(std::move(Profile));
380
381 ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
382 ASSERT_TRUE(NoError(R.getError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000383 ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
384 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
385 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
386 ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
387 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000388
Xinliang David Li1e4c8092016-02-04 05:29:51 +0000389 uint64_t TotalC;
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000390 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000391 R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000392 ASSERT_EQ(30U, VD[0].Count);
393 ASSERT_EQ(20U, VD[1].Count);
394 ASSERT_EQ(10U, VD[2].Count);
Xinliang David Li1e4c8092016-02-04 05:29:51 +0000395 ASSERT_EQ(60U, TotalC);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000396
Xinliang David Li2004f002015-11-02 05:08:23 +0000397 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
398 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
399 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
400}
401
Vedant Kumar00dab222016-01-29 22:54:45 +0000402TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_big_endian) {
Xinliang David Li46ad3632016-01-22 19:53:31 +0000403 InstrProfRecord Record1("caller", 0x1234, {1, 2});
404 InstrProfRecord Record2("callee1", 0x1235, {3, 4});
405 InstrProfRecord Record3("callee2", 0x1235, {3, 4});
406 InstrProfRecord Record4("callee3", 0x1235, {3, 4});
407
408 // 4 value sites.
409 Record1.reserveSites(IPVK_IndirectCallTarget, 4);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000410 InstrProfValueData VD0[] = {
411 {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
Xinliang David Li46ad3632016-01-22 19:53:31 +0000412 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
413 // No value profile data at the second site.
414 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000415 InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
Xinliang David Li46ad3632016-01-22 19:53:31 +0000416 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000417 InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
Xinliang David Li46ad3632016-01-22 19:53:31 +0000418 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
419
Vedant Kumarec210812016-05-03 17:07:06 +0000420 NoError(Writer.addRecord(std::move(Record1)));
421 NoError(Writer.addRecord(std::move(Record2)));
422 NoError(Writer.addRecord(std::move(Record3)));
423 NoError(Writer.addRecord(std::move(Record4)));
Xinliang David Li46ad3632016-01-22 19:53:31 +0000424
425 // Set big endian output.
426 Writer.setValueProfDataEndianness(support::big);
427
428 auto Profile = Writer.writeBuffer();
429 readProfile(std::move(Profile));
430
431 // Set big endian input.
432 Reader->setValueProfDataEndianness(support::big);
433
434 ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
435 ASSERT_TRUE(NoError(R.getError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000436 ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
437 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
438 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
439 ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
440 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
Xinliang David Li46ad3632016-01-22 19:53:31 +0000441
442 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000443 R->getValueForSite(IPVK_IndirectCallTarget, 0);
Xinliang David Li46ad3632016-01-22 19:53:31 +0000444 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
445 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
446 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
447
448 // Restore little endian default:
449 Writer.setValueProfDataEndianness(support::little);
450}
451
Vedant Kumar00dab222016-01-29 22:54:45 +0000452TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge1) {
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000453 static const char caller[] = "caller";
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000454 InstrProfRecord Record11(caller, 0x1234, {1, 2});
455 InstrProfRecord Record12(caller, 0x1234, {1, 2});
456 InstrProfRecord Record2(callee1, 0x1235, {3, 4});
457 InstrProfRecord Record3(callee2, 0x1235, {3, 4});
458 InstrProfRecord Record4(callee3, 0x1235, {3, 4});
459 InstrProfRecord Record5(callee3, 0x1235, {3, 4});
460 InstrProfRecord Record6(callee4, 0x1235, {3, 5});
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
Vedant Kumarec210812016-05-03 17:07:06 +0000508 NoError(Writer.addRecord(std::move(Record2)));
509 NoError(Writer.addRecord(std::move(Record3)));
510 NoError(Writer.addRecord(std::move(Record4)));
511 NoError(Writer.addRecord(std::move(Record5)));
512 NoError(Writer.addRecord(std::move(Record6)));
Xinliang David Li2004f002015-11-02 05:08:23 +0000513 auto Profile = Writer.writeBuffer();
514 readProfile(std::move(Profile));
515
516 ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
517 ASSERT_TRUE(NoError(R.getError()));
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
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000567 InstrProfRecord Record1("foo", 0x1234, {1});
568 auto Result1 = Writer.addRecord(std::move(Record1));
569 ASSERT_EQ(Result1, instrprof_error::success);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000570
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000571 // Verify counter overflow.
572 InstrProfRecord Record2("foo", 0x1234, {Max});
573 auto Result2 = Writer.addRecord(std::move(Record2));
574 ASSERT_EQ(Result2, instrprof_error::counter_overflow);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000575
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000576 InstrProfRecord Record3(bar, 0x9012, {8});
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000577 auto Result3 = Writer.addRecord(std::move(Record3));
578 ASSERT_EQ(Result3, instrprof_error::success);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000579
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000580 InstrProfRecord Record4("baz", 0x5678, {3, 4});
581 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));
585 ASSERT_EQ(Result4, instrprof_error::success);
586
587 // Verify value data counter overflow.
588 InstrProfRecord Record5("baz", 0x5678, {5, 6});
589 Record5.reserveSites(IPVK_IndirectCallTarget, 1);
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000590 InstrProfValueData VD5[] = {{uint64_t(bar), Max}};
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000591 Record5.addValueData(IPVK_IndirectCallTarget, 0, VD5, 1, nullptr);
592 auto Result5 = Writer.addRecord(std::move(Record5));
593 ASSERT_EQ(Result5, instrprof_error::counter_overflow);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000594
595 auto Profile = Writer.writeBuffer();
596 readProfile(std::move(Profile));
597
598 // Verify saturation of counts.
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000599 ErrorOr<InstrProfRecord> ReadRecord1 =
600 Reader->getInstrProfRecord("foo", 0x1234);
601 ASSERT_TRUE(NoError(ReadRecord1.getError()));
David Blaikiefed557e2016-02-09 01:02:24 +0000602 ASSERT_EQ(Max, ReadRecord1->Counts[0]);
Nathan Slingerlandaa5702d2015-12-02 18:19:24 +0000603
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000604 ErrorOr<InstrProfRecord> ReadRecord2 =
605 Reader->getInstrProfRecord("baz", 0x5678);
David Blaikiefed557e2016-02-09 01:02:24 +0000606 ASSERT_EQ(1U, ReadRecord2->getNumValueSites(IPVK_IndirectCallTarget));
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000607 std::unique_ptr<InstrProfValueData[]> VD =
David Blaikiefed557e2016-02-09 01:02:24 +0000608 ReadRecord2->getValueForSite(IPVK_IndirectCallTarget, 0);
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000609 ASSERT_EQ(StringRef("bar"), StringRef((const char *)VD[0].Value, 3));
610 ASSERT_EQ(Max, VD[0].Count);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000611}
612
Xinliang David Li872df222016-01-08 06:54:27 +0000613// This test tests that when there are too many values
614// for a given site, the merged results are properly
615// truncated.
Vedant Kumar00dab222016-01-29 22:54:45 +0000616TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge_site_trunc) {
Xinliang David Li872df222016-01-08 06:54:27 +0000617 static const char caller[] = "caller";
618
619 InstrProfRecord Record11(caller, 0x1234, {1, 2});
620 InstrProfRecord Record12(caller, 0x1234, {1, 2});
621
622 // 2 value sites.
623 Record11.reserveSites(IPVK_IndirectCallTarget, 2);
624 InstrProfValueData VD0[255];
625 for (int I = 0; I < 255; I++) {
626 VD0[I].Value = 2 * I;
627 VD0[I].Count = 2 * I + 1000;
628 }
629
630 Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 255, nullptr);
631 Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
632
633 Record12.reserveSites(IPVK_IndirectCallTarget, 2);
634 InstrProfValueData VD1[255];
635 for (int I = 0; I < 255; I++) {
636 VD1[I].Value = 2 * I + 1;
637 VD1[I].Count = 2 * I + 1001;
638 }
639
640 Record12.addValueData(IPVK_IndirectCallTarget, 0, VD1, 255, nullptr);
641 Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
642
Vedant Kumarec210812016-05-03 17:07:06 +0000643 NoError(Writer.addRecord(std::move(Record11)));
Xinliang David Li872df222016-01-08 06:54:27 +0000644 // Merge profile data.
Vedant Kumarec210812016-05-03 17:07:06 +0000645 NoError(Writer.addRecord(std::move(Record12)));
Xinliang David Li872df222016-01-08 06:54:27 +0000646
647 auto Profile = Writer.writeBuffer();
648 readProfile(std::move(Profile));
649
650 ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
651 ASSERT_TRUE(NoError(R.getError()));
652 std::unique_ptr<InstrProfValueData[]> VD(
David Blaikiefed557e2016-02-09 01:02:24 +0000653 R->getValueForSite(IPVK_IndirectCallTarget, 0));
654 ASSERT_EQ(2U, R->getNumValueSites(IPVK_IndirectCallTarget));
655 ASSERT_EQ(255U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
NAKAMURA Takumi249edf32016-01-08 07:58:20 +0000656 for (unsigned I = 0; I < 255; I++) {
Xinliang David Li872df222016-01-08 06:54:27 +0000657 ASSERT_EQ(VD[I].Value, 509 - I);
658 ASSERT_EQ(VD[I].Count, 1509 - I);
659 }
660}
661
Xinliang David Lied966772015-11-25 23:31:18 +0000662// Synthesize runtime value profile data.
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000663ValueProfNode Site1Values[5] = {{{uint64_t(callee1), 400}, &Site1Values[1]},
664 {{uint64_t(callee2), 1000}, &Site1Values[2]},
665 {{uint64_t(callee3), 500}, &Site1Values[3]},
666 {{uint64_t(callee4), 300}, &Site1Values[4]},
667 {{uint64_t(callee5), 100}, nullptr}};
Xinliang David Lied966772015-11-25 23:31:18 +0000668
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000669ValueProfNode Site2Values[4] = {{{uint64_t(callee5), 800}, &Site2Values[1]},
670 {{uint64_t(callee3), 1000}, &Site2Values[2]},
671 {{uint64_t(callee2), 2500}, &Site2Values[3]},
672 {{uint64_t(callee1), 1300}, nullptr}};
Xinliang David Lied966772015-11-25 23:31:18 +0000673
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000674ValueProfNode Site3Values[3] = {{{uint64_t(callee6), 800}, &Site3Values[1]},
675 {{uint64_t(callee3), 1000}, &Site3Values[2]},
676 {{uint64_t(callee4), 5500}, nullptr}};
Xinliang David Lied966772015-11-25 23:31:18 +0000677
Xinliang David Lia3e0d452016-04-10 02:35:53 +0000678ValueProfNode Site4Values[2] = {{{uint64_t(callee2), 1800}, &Site4Values[1]},
679 {{uint64_t(callee3), 2000}, nullptr}};
Xinliang David Lied966772015-11-25 23:31:18 +0000680
681static ValueProfNode *ValueProfNodes[5] = {&Site1Values[0], &Site2Values[0],
Eugene Zelenko6ac3f732016-01-26 18:48:36 +0000682 &Site3Values[0], &Site4Values[0],
683 nullptr};
684
Xinliang David Lied966772015-11-25 23:31:18 +0000685static uint16_t NumValueSites[IPVK_Last + 1] = {5};
Vedant Kumar00dab222016-01-29 22:54:45 +0000686TEST_P(MaybeSparseInstrProfTest, runtime_value_prof_data_read_write) {
Xinliang David Lied966772015-11-25 23:31:18 +0000687 ValueProfRuntimeRecord RTRecord;
688 initializeValueProfRuntimeRecord(&RTRecord, &NumValueSites[0],
689 &ValueProfNodes[0]);
690
Xinliang David Li0e6a36e2015-12-01 19:47:32 +0000691 ValueProfData *VPData = serializeValueProfDataFromRT(&RTRecord, nullptr);
Xinliang David Lied966772015-11-25 23:31:18 +0000692
693 InstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2});
694
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);
751
752 finalizeValueProfRuntimeRecord(&RTRecord);
753 free(VPData);
754}
755
Xinliang David Li28464482016-04-10 03:32:02 +0000756static uint16_t NumValueSites2[IPVK_Last + 1] = {1};
757TEST_P(MaybeSparseInstrProfTest, runtime_value_prof_data_read_write_mapping) {
758 ValueProfRuntimeRecord RTRecord;
759 initializeValueProfRuntimeRecord(&RTRecord, &NumValueSites2[0],
760 &ValueProfNodes[0]);
761
762 ValueProfData *VPData = serializeValueProfDataFromRT(&RTRecord, nullptr);
763
764 InstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2});
765 InstrProfSymtab Symtab;
766 Symtab.mapAddress(uint64_t(callee1), 0x1000ULL);
767 Symtab.mapAddress(uint64_t(callee2), 0x2000ULL);
768 Symtab.mapAddress(uint64_t(callee3), 0x3000ULL);
769 Symtab.mapAddress(uint64_t(callee4), 0x4000ULL);
770 // Missing mapping for callee5
771 Symtab.finalizeSymtab();
772
773 VPData->deserializeTo(Record, &Symtab.getAddrHashMap());
774
775 // Now read data from Record and sanity check the data
776 ASSERT_EQ(1U, Record.getNumValueSites(IPVK_IndirectCallTarget));
777 ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
778
779 auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
780 return VD1.Count > VD2.Count;
781 };
782 std::unique_ptr<InstrProfValueData[]> VD_0(
783 Record.getValueForSite(IPVK_IndirectCallTarget, 0));
784 std::sort(&VD_0[0], &VD_0[5], Cmp);
785 ASSERT_EQ(VD_0[0].Value, 0x2000ULL);
786 ASSERT_EQ(1000U, VD_0[0].Count);
787 ASSERT_EQ(VD_0[1].Value, 0x3000ULL);
788 ASSERT_EQ(500U, VD_0[1].Count);
789 ASSERT_EQ(VD_0[2].Value, 0x1000ULL);
790 ASSERT_EQ(400U, VD_0[2].Count);
791
792 // callee5 does not have a mapped value -- default to 0.
793 ASSERT_EQ(VD_0[4].Value, 0ULL);
Xinliang David Li06d6ce22016-04-10 05:31:29 +0000794 finalizeValueProfRuntimeRecord(&RTRecord);
795 free(VPData);
Xinliang David Li28464482016-04-10 03:32:02 +0000796}
797
Vedant Kumar00dab222016-01-29 22:54:45 +0000798TEST_P(MaybeSparseInstrProfTest, get_max_function_count) {
Justin Bogner9e9a0572015-09-29 22:13:58 +0000799 InstrProfRecord Record1("foo", 0x1234, {1ULL << 31, 2});
800 InstrProfRecord Record2("bar", 0, {1ULL << 63});
801 InstrProfRecord Record3("baz", 0x5678, {0, 0, 0, 0});
Vedant Kumarec210812016-05-03 17:07:06 +0000802 NoError(Writer.addRecord(std::move(Record1)));
803 NoError(Writer.addRecord(std::move(Record2)));
804 NoError(Writer.addRecord(std::move(Record3)));
Justin Bogner2b6c5372015-02-18 01:58:17 +0000805 auto Profile = Writer.writeBuffer();
806 readProfile(std::move(Profile));
807
808 ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount());
809}
810
Vedant Kumar00dab222016-01-29 22:54:45 +0000811TEST_P(MaybeSparseInstrProfTest, get_weighted_function_counts) {
Nathan Slingerland7f5b47d2015-12-15 17:37:09 +0000812 InstrProfRecord Record1("foo", 0x1234, {1, 2});
813 InstrProfRecord Record2("foo", 0x1235, {3, 4});
Vedant Kumarec210812016-05-03 17:07:06 +0000814 NoError(Writer.addRecord(std::move(Record1), 3));
815 NoError(Writer.addRecord(std::move(Record2), 5));
Nathan Slingerland7f5b47d2015-12-15 17:37:09 +0000816 auto Profile = Writer.writeBuffer();
817 readProfile(std::move(Profile));
818
819 std::vector<uint64_t> Counts;
820 ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1234, Counts)));
821 ASSERT_EQ(2U, Counts.size());
822 ASSERT_EQ(3U, Counts[0]);
823 ASSERT_EQ(6U, Counts[1]);
824
825 ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1235, Counts)));
826 ASSERT_EQ(2U, Counts.size());
827 ASSERT_EQ(15U, Counts[0]);
828 ASSERT_EQ(20U, Counts[1]);
829}
830
Xinliang David Lia0601e72016-02-09 05:47:08 +0000831// Testing symtab creator interface used by indexed profile reader.
Vedant Kumar00dab222016-01-29 22:54:45 +0000832TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_test) {
Xinliang David Li2ee5c4d2015-12-19 07:44:57 +0000833 std::vector<StringRef> FuncNames;
834 FuncNames.push_back("func1");
835 FuncNames.push_back("func2");
836 FuncNames.push_back("func3");
837 FuncNames.push_back("bar1");
838 FuncNames.push_back("bar2");
839 FuncNames.push_back("bar3");
840 InstrProfSymtab Symtab;
841 Symtab.create(FuncNames);
842 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
843 ASSERT_EQ(StringRef("func1"), R);
844 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
845 ASSERT_EQ(StringRef("func2"), R);
846 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
847 ASSERT_EQ(StringRef("func3"), R);
848 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
849 ASSERT_EQ(StringRef("bar1"), R);
850 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
851 ASSERT_EQ(StringRef("bar2"), R);
852 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
853 ASSERT_EQ(StringRef("bar3"), R);
Xinliang David Lic96d3d12015-12-19 18:20:09 +0000854
Xinliang David Li86b4b912016-02-10 06:36:55 +0000855 // negative tests
856 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar4"));
857 ASSERT_EQ(StringRef(), R);
858 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("foo4"));
859 ASSERT_EQ(StringRef(), R);
860
Xinliang David Lic96d3d12015-12-19 18:20:09 +0000861 // Now incrementally update the symtab
862 Symtab.addFuncName("blah_1");
863 Symtab.addFuncName("blah_2");
864 Symtab.addFuncName("blah_3");
865 // Finalize it
866 Symtab.finalizeSymtab();
867
868 // Check again
869 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_1"));
870 ASSERT_EQ(StringRef("blah_1"), R);
871 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_2"));
872 ASSERT_EQ(StringRef("blah_2"), R);
873 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_3"));
874 ASSERT_EQ(StringRef("blah_3"), R);
875 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
876 ASSERT_EQ(StringRef("func1"), R);
877 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
878 ASSERT_EQ(StringRef("func2"), R);
879 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
880 ASSERT_EQ(StringRef("func3"), R);
881 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
882 ASSERT_EQ(StringRef("bar1"), R);
883 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
884 ASSERT_EQ(StringRef("bar2"), R);
885 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
886 ASSERT_EQ(StringRef("bar3"), R);
Xinliang David Li2ee5c4d2015-12-19 07:44:57 +0000887}
888
Xinliang David Lia0601e72016-02-09 05:47:08 +0000889// Testing symtab creator interface used by value profile transformer.
Vedant Kumar00dab222016-01-29 22:54:45 +0000890TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_module_test) {
Xinliang David Li59411db2016-01-20 01:26:34 +0000891 LLVMContext Ctx;
892 std::unique_ptr<Module> M = llvm::make_unique<Module>("MyModule.cpp", Ctx);
893 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
894 /*isVarArg=*/false);
895 Function::Create(FTy, Function::ExternalLinkage, "Gfoo", M.get());
896 Function::Create(FTy, Function::ExternalLinkage, "Gblah", M.get());
897 Function::Create(FTy, Function::ExternalLinkage, "Gbar", M.get());
898 Function::Create(FTy, Function::InternalLinkage, "Ifoo", M.get());
899 Function::Create(FTy, Function::InternalLinkage, "Iblah", M.get());
900 Function::Create(FTy, Function::InternalLinkage, "Ibar", M.get());
901 Function::Create(FTy, Function::PrivateLinkage, "Pfoo", M.get());
902 Function::Create(FTy, Function::PrivateLinkage, "Pblah", M.get());
903 Function::Create(FTy, Function::PrivateLinkage, "Pbar", M.get());
904 Function::Create(FTy, Function::WeakODRLinkage, "Wfoo", M.get());
905 Function::Create(FTy, Function::WeakODRLinkage, "Wblah", M.get());
906 Function::Create(FTy, Function::WeakODRLinkage, "Wbar", M.get());
907
908 InstrProfSymtab ProfSymtab;
David Blaikiefed557e2016-02-09 01:02:24 +0000909 ProfSymtab.create(*M);
Xinliang David Li59411db2016-01-20 01:26:34 +0000910
911 StringRef Funcs[] = {"Gfoo", "Gblah", "Gbar", "Ifoo", "Iblah", "Ibar",
912 "Pfoo", "Pblah", "Pbar", "Wfoo", "Wblah", "Wbar"};
913
914 for (unsigned I = 0; I < sizeof(Funcs) / sizeof(*Funcs); I++) {
915 Function *F = M->getFunction(Funcs[I]);
Eugene Zelenko6ac3f732016-01-26 18:48:36 +0000916 ASSERT_TRUE(F != nullptr);
Xinliang David Lida656fe2016-01-20 02:49:53 +0000917 std::string PGOName = getPGOFuncName(*F);
Xinliang David Li3865fdc2016-01-22 18:13:34 +0000918 uint64_t Key = IndexedInstrProf::ComputeHash(PGOName);
Xinliang David Lida656fe2016-01-20 02:49:53 +0000919 ASSERT_EQ(StringRef(PGOName),
Xinliang David Li3865fdc2016-01-22 18:13:34 +0000920 ProfSymtab.getFuncName(Key));
921 ASSERT_EQ(StringRef(Funcs[I]), ProfSymtab.getOrigFuncName(Key));
Xinliang David Li59411db2016-01-20 01:26:34 +0000922 }
923}
924
Xinliang David Lia0601e72016-02-09 05:47:08 +0000925// Testing symtab serialization and creator/deserialization interface
926// used by coverage map reader, and raw profile reader.
Vedant Kumar00dab222016-01-29 22:54:45 +0000927TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_compression_test) {
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000928 std::vector<std::string> FuncNames1;
929 std::vector<std::string> FuncNames2;
Xinliang David Lic2f25cc42016-02-09 05:36:57 +0000930 for (int I = 0; I < 3; I++) {
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000931 std::string str;
932 raw_string_ostream OS(str);
933 OS << "func_" << I;
934 FuncNames1.push_back(OS.str());
935 str.clear();
Vedant Kumar86705ba2016-03-28 21:06:42 +0000936 OS << "f oooooooooooooo_" << I;
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000937 FuncNames1.push_back(OS.str());
938 str.clear();
939 OS << "BAR_" << I;
940 FuncNames2.push_back(OS.str());
941 str.clear();
942 OS << "BlahblahBlahblahBar_" << I;
943 FuncNames2.push_back(OS.str());
944 }
945
Xinliang David Lidd4ae7b2016-01-29 22:29:15 +0000946 for (bool DoCompression : {false, true}) {
947 // Compressing:
948 std::string FuncNameStrings1;
Vedant Kumarec210812016-05-03 17:07:06 +0000949 NoError(collectPGOFuncNameStrings(
950 FuncNames1, (DoCompression && zlib::isAvailable()), FuncNameStrings1));
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000951
Xinliang David Lidd4ae7b2016-01-29 22:29:15 +0000952 // Compressing:
953 std::string FuncNameStrings2;
Vedant Kumarec210812016-05-03 17:07:06 +0000954 NoError(collectPGOFuncNameStrings(
955 FuncNames2, (DoCompression && zlib::isAvailable()), FuncNameStrings2));
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000956
Xinliang David Lic2f25cc42016-02-09 05:36:57 +0000957 for (int Padding = 0; Padding < 2; Padding++) {
958 // Join with paddings :
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000959 std::string FuncNameStrings = FuncNameStrings1;
960 for (int P = 0; P < Padding; P++) {
961 FuncNameStrings.push_back('\0');
962 }
963 FuncNameStrings += FuncNameStrings2;
964
Xinliang David Li8dec8b12016-01-04 23:59:14 +0000965 // Now decompress:
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000966 InstrProfSymtab Symtab;
Vedant Kumarec210812016-05-03 17:07:06 +0000967 NoError(Symtab.create(StringRef(FuncNameStrings)));
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000968
Xinliang David Li8dec8b12016-01-04 23:59:14 +0000969 // Now do the checks:
970 // First sampling some data points:
Xinliang David Lia8ba7af2016-01-29 21:26:31 +0000971 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[0]));
Xinliang David Li8dec8b12016-01-04 23:59:14 +0000972 ASSERT_EQ(StringRef("func_0"), R);
973 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[1]));
Vedant Kumar86705ba2016-03-28 21:06:42 +0000974 ASSERT_EQ(StringRef("f oooooooooooooo_0"), R);
Xinliang David Lic2f25cc42016-02-09 05:36:57 +0000975 for (int I = 0; I < 3; I++) {
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000976 std::string N[4];
977 N[0] = FuncNames1[2 * I];
978 N[1] = FuncNames1[2 * I + 1];
979 N[2] = FuncNames2[2 * I];
980 N[3] = FuncNames2[2 * I + 1];
981 for (int J = 0; J < 4; J++) {
982 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(N[J]));
983 ASSERT_EQ(StringRef(N[J]), R);
984 }
985 }
986 }
987 }
988}
989
Vedant Kumar00dab222016-01-29 22:54:45 +0000990TEST_F(SparseInstrProfTest, preserve_no_records) {
991 InstrProfRecord Record1("foo", 0x1234, {0});
992 InstrProfRecord Record2("bar", 0x4321, {0, 0});
993 InstrProfRecord Record3("bar", 0x4321, {0, 0, 0});
994
Vedant Kumarec210812016-05-03 17:07:06 +0000995 NoError(Writer.addRecord(std::move(Record1)));
996 NoError(Writer.addRecord(std::move(Record2)));
997 NoError(Writer.addRecord(std::move(Record3)));
Vedant Kumar00dab222016-01-29 22:54:45 +0000998 auto Profile = Writer.writeBuffer();
999 readProfile(std::move(Profile));
1000
1001 auto I = Reader->begin(), E = Reader->end();
1002 ASSERT_TRUE(I == E);
1003}
1004
1005INSTANTIATE_TEST_CASE_P(MaybeSparse, MaybeSparseInstrProfTest,
1006 ::testing::Bool());
1007
Justin Bogner2b6c5372015-02-18 01:58:17 +00001008} // end anonymous namespace