blob: 77c2e0cebdf63a8b8722058f31cebe8184946aa1 [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"
11#include "llvm/IR/LLVMContext.h"
12#include "llvm/IR/Module.h"
Justin Bogner2b6c5372015-02-18 01:58:17 +000013#include "llvm/ProfileData/InstrProfReader.h"
14#include "llvm/ProfileData/InstrProfWriter.h"
Xinliang David Li876c2022016-01-22 05:48:40 +000015#include "llvm/Support/CommandLine.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"
18
19#include <cstdarg>
20
21using namespace llvm;
22
23static ::testing::AssertionResult NoError(std::error_code EC) {
24 if (!EC)
25 return ::testing::AssertionSuccess();
26 return ::testing::AssertionFailure() << "error " << EC.value()
27 << ": " << EC.message();
28}
29
30static ::testing::AssertionResult ErrorEquals(std::error_code Expected,
31 std::error_code Found) {
32 if (Expected == Found)
33 return ::testing::AssertionSuccess();
34 return ::testing::AssertionFailure() << "error " << Found.value()
35 << ": " << Found.message();
36}
37
38namespace {
39
40struct InstrProfTest : ::testing::Test {
41 InstrProfWriter Writer;
42 std::unique_ptr<IndexedInstrProfReader> Reader;
43
44 void readProfile(std::unique_ptr<MemoryBuffer> Profile) {
45 auto ReaderOrErr = IndexedInstrProfReader::create(std::move(Profile));
46 ASSERT_TRUE(NoError(ReaderOrErr.getError()));
47 Reader = std::move(ReaderOrErr.get());
48 }
49};
50
51TEST_F(InstrProfTest, write_and_read_empty_profile) {
52 auto Profile = Writer.writeBuffer();
53 readProfile(std::move(Profile));
54 ASSERT_TRUE(Reader->begin() == Reader->end());
55}
56
57TEST_F(InstrProfTest, write_and_read_one_function) {
Justin Bogner9e9a0572015-09-29 22:13:58 +000058 InstrProfRecord Record("foo", 0x1234, {1, 2, 3, 4});
59 Writer.addRecord(std::move(Record));
Justin Bogner2b6c5372015-02-18 01:58:17 +000060 auto Profile = Writer.writeBuffer();
61 readProfile(std::move(Profile));
62
63 auto I = Reader->begin(), E = Reader->end();
64 ASSERT_TRUE(I != E);
65 ASSERT_EQ(StringRef("foo"), I->Name);
66 ASSERT_EQ(0x1234U, I->Hash);
67 ASSERT_EQ(4U, I->Counts.size());
68 ASSERT_EQ(1U, I->Counts[0]);
69 ASSERT_EQ(2U, I->Counts[1]);
70 ASSERT_EQ(3U, I->Counts[2]);
71 ASSERT_EQ(4U, I->Counts[3]);
72 ASSERT_TRUE(++I == E);
73}
74
Xinliang David Li2004f002015-11-02 05:08:23 +000075TEST_F(InstrProfTest, get_instr_prof_record) {
76 InstrProfRecord Record1("foo", 0x1234, {1, 2});
77 InstrProfRecord Record2("foo", 0x1235, {3, 4});
78 Writer.addRecord(std::move(Record1));
79 Writer.addRecord(std::move(Record2));
80 auto Profile = Writer.writeBuffer();
81 readProfile(std::move(Profile));
82
83 ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("foo", 0x1234);
84 ASSERT_TRUE(NoError(R.getError()));
85 ASSERT_EQ(2U, R.get().Counts.size());
86 ASSERT_EQ(1U, R.get().Counts[0]);
87 ASSERT_EQ(2U, R.get().Counts[1]);
88
89 R = Reader->getInstrProfRecord("foo", 0x1235);
90 ASSERT_TRUE(NoError(R.getError()));
91 ASSERT_EQ(2U, R.get().Counts.size());
92 ASSERT_EQ(3U, R.get().Counts[0]);
93 ASSERT_EQ(4U, R.get().Counts[1]);
94
95 R = Reader->getInstrProfRecord("foo", 0x5678);
96 ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, R.getError()));
97
98 R = Reader->getInstrProfRecord("bar", 0x1234);
99 ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, R.getError()));
100}
101
Justin Bogner2b6c5372015-02-18 01:58:17 +0000102TEST_F(InstrProfTest, get_function_counts) {
Justin Bogner9e9a0572015-09-29 22:13:58 +0000103 InstrProfRecord Record1("foo", 0x1234, {1, 2});
104 InstrProfRecord Record2("foo", 0x1235, {3, 4});
105 Writer.addRecord(std::move(Record1));
106 Writer.addRecord(std::move(Record2));
Justin Bogner2b6c5372015-02-18 01:58:17 +0000107 auto Profile = Writer.writeBuffer();
108 readProfile(std::move(Profile));
109
110 std::vector<uint64_t> Counts;
111 ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1234, Counts)));
112 ASSERT_EQ(2U, Counts.size());
113 ASSERT_EQ(1U, Counts[0]);
114 ASSERT_EQ(2U, Counts[1]);
115
Justin Bogner09829f42015-06-22 23:56:53 +0000116 ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1235, Counts)));
117 ASSERT_EQ(2U, Counts.size());
118 ASSERT_EQ(3U, Counts[0]);
119 ASSERT_EQ(4U, Counts[1]);
120
Justin Bogner2b6c5372015-02-18 01:58:17 +0000121 std::error_code EC;
122 EC = Reader->getFunctionCounts("foo", 0x5678, Counts);
123 ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, EC));
124
125 EC = Reader->getFunctionCounts("bar", 0x1234, Counts);
126 ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, EC));
127}
128
Xinliang David Li2004f002015-11-02 05:08:23 +0000129TEST_F(InstrProfTest, get_icall_data_read_write) {
130 InstrProfRecord Record1("caller", 0x1234, {1, 2});
131 InstrProfRecord Record2("callee1", 0x1235, {3, 4});
132 InstrProfRecord Record3("callee2", 0x1235, {3, 4});
133 InstrProfRecord Record4("callee3", 0x1235, {3, 4});
134
135 // 4 value sites.
136 Record1.reserveSites(IPVK_IndirectCallTarget, 4);
137 InstrProfValueData VD0[] = {{(uint64_t) "callee1", 1},
138 {(uint64_t) "callee2", 2},
139 {(uint64_t) "callee3", 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000140 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
Xinliang David Liee415892015-11-10 00:24:45 +0000141 // No value profile data at the second site.
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000142 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000143 InstrProfValueData VD2[] = {{(uint64_t) "callee1", 1},
144 {(uint64_t) "callee2", 2}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000145 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000146 InstrProfValueData VD3[] = {{(uint64_t) "callee1", 1}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000147 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000148
Xinliang David Li876c2022016-01-22 05:48:40 +0000149 ASSERT_EQ(support::little, InstrProfWriter::getValueProfDataEndianness());
Xinliang David Li2004f002015-11-02 05:08:23 +0000150 Writer.addRecord(std::move(Record1));
151 Writer.addRecord(std::move(Record2));
152 Writer.addRecord(std::move(Record3));
153 Writer.addRecord(std::move(Record4));
154 auto Profile = Writer.writeBuffer();
155 readProfile(std::move(Profile));
156
157 ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
158 ASSERT_TRUE(NoError(R.getError()));
159 ASSERT_EQ(4U, R.get().getNumValueSites(IPVK_IndirectCallTarget));
160 ASSERT_EQ(3U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
161 ASSERT_EQ(0U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
162 ASSERT_EQ(2U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
163 ASSERT_EQ(1U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
164
165 std::unique_ptr<InstrProfValueData[]> VD =
166 R.get().getValueForSite(IPVK_IndirectCallTarget, 0);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000167
168 ASSERT_EQ(3U, VD[0].Count);
169 ASSERT_EQ(2U, VD[1].Count);
170 ASSERT_EQ(1U, VD[2].Count);
171
172 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
173 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
174 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
175}
176
177TEST_F(InstrProfTest, get_icall_data_read_write_with_weight) {
178 InstrProfRecord Record1("caller", 0x1234, {1, 2});
179 InstrProfRecord Record2("callee1", 0x1235, {3, 4});
180 InstrProfRecord Record3("callee2", 0x1235, {3, 4});
181 InstrProfRecord Record4("callee3", 0x1235, {3, 4});
182
183 // 4 value sites.
184 Record1.reserveSites(IPVK_IndirectCallTarget, 4);
185 InstrProfValueData VD0[] = {{(uint64_t) "callee1", 1},
186 {(uint64_t) "callee2", 2},
187 {(uint64_t) "callee3", 3}};
188 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
189 // No value profile data at the second site.
190 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
191 InstrProfValueData VD2[] = {{(uint64_t) "callee1", 1},
192 {(uint64_t) "callee2", 2}};
193 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
194 InstrProfValueData VD3[] = {{(uint64_t) "callee1", 1}};
195 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
196
Xinliang David Li876c2022016-01-22 05:48:40 +0000197 ASSERT_EQ(support::little, InstrProfWriter::getValueProfDataEndianness());
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000198 Writer.addRecord(std::move(Record1), 10);
199 Writer.addRecord(std::move(Record2));
200 Writer.addRecord(std::move(Record3));
201 Writer.addRecord(std::move(Record4));
202 auto Profile = Writer.writeBuffer();
203 readProfile(std::move(Profile));
204
205 ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
206 ASSERT_TRUE(NoError(R.getError()));
207 ASSERT_EQ(4U, R.get().getNumValueSites(IPVK_IndirectCallTarget));
208 ASSERT_EQ(3U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
209 ASSERT_EQ(0U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
210 ASSERT_EQ(2U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
211 ASSERT_EQ(1U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
212
213 std::unique_ptr<InstrProfValueData[]> VD =
214 R.get().getValueForSite(IPVK_IndirectCallTarget, 0);
Xinliang David Li51dc04c2016-01-08 03:49:59 +0000215 ASSERT_EQ(30U, VD[0].Count);
216 ASSERT_EQ(20U, VD[1].Count);
217 ASSERT_EQ(10U, VD[2].Count);
218
Xinliang David Li2004f002015-11-02 05:08:23 +0000219 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
220 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
221 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
222}
223
224TEST_F(InstrProfTest, get_icall_data_merge1) {
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000225 static const char caller[] = "caller";
226 static const char callee1[] = "callee1";
227 static const char callee2[] = "callee2";
228 static const char callee3[] = "callee3";
229 static const char callee4[] = "callee4";
230
231 InstrProfRecord Record11(caller, 0x1234, {1, 2});
232 InstrProfRecord Record12(caller, 0x1234, {1, 2});
233 InstrProfRecord Record2(callee1, 0x1235, {3, 4});
234 InstrProfRecord Record3(callee2, 0x1235, {3, 4});
235 InstrProfRecord Record4(callee3, 0x1235, {3, 4});
236 InstrProfRecord Record5(callee3, 0x1235, {3, 4});
237 InstrProfRecord Record6(callee4, 0x1235, {3, 5});
Xinliang David Li2004f002015-11-02 05:08:23 +0000238
239 // 5 value sites.
240 Record11.reserveSites(IPVK_IndirectCallTarget, 5);
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000241 InstrProfValueData VD0[] = {{uint64_t(callee1), 1},
242 {uint64_t(callee2), 2},
243 {uint64_t(callee3), 3},
244 {uint64_t(callee4), 4}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000245 Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 4, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000246
Xinliang David Li872df222016-01-08 06:54:27 +0000247 // No value profile data at the second site.
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000248 Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000249
Xinliang David Li872df222016-01-08 06:54:27 +0000250 InstrProfValueData VD2[] = {
251 {uint64_t(callee1), 1}, {uint64_t(callee2), 2}, {uint64_t(callee3), 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000252 Record11.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000253
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000254 InstrProfValueData VD3[] = {{uint64_t(callee1), 1}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000255 Record11.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000256
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000257 InstrProfValueData VD4[] = {{uint64_t(callee1), 1},
258 {uint64_t(callee2), 2},
259 {uint64_t(callee3), 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000260 Record11.addValueData(IPVK_IndirectCallTarget, 4, VD4, 3, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000261
262 // A differnt record for the same caller.
263 Record12.reserveSites(IPVK_IndirectCallTarget, 5);
Xinliang David Li872df222016-01-08 06:54:27 +0000264 InstrProfValueData VD02[] = {{uint64_t(callee2), 5}, {uint64_t(callee3), 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000265 Record12.addValueData(IPVK_IndirectCallTarget, 0, VD02, 2, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000266
Xinliang David Li872df222016-01-08 06:54:27 +0000267 // No value profile data at the second site.
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000268 Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000269
Xinliang David Li872df222016-01-08 06:54:27 +0000270 InstrProfValueData VD22[] = {
271 {uint64_t(callee2), 1}, {uint64_t(callee3), 3}, {uint64_t(callee4), 4}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000272 Record12.addValueData(IPVK_IndirectCallTarget, 2, VD22, 3, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000273
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000274 Record12.addValueData(IPVK_IndirectCallTarget, 3, nullptr, 0, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000275
Xinliang David Li876c2022016-01-22 05:48:40 +0000276 InstrProfValueData VD42[] = {
277 {uint64_t(callee1), 1}, {uint64_t(callee2), 2}, {uint64_t(callee3), 3}};
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000278 Record12.addValueData(IPVK_IndirectCallTarget, 4, VD42, 3, nullptr);
Xinliang David Li2004f002015-11-02 05:08:23 +0000279
Xinliang David Li876c2022016-01-22 05:48:40 +0000280 ASSERT_EQ(support::little, InstrProfWriter::getValueProfDataEndianness());
Xinliang David Li2004f002015-11-02 05:08:23 +0000281 Writer.addRecord(std::move(Record11));
282 // Merge profile data.
283 Writer.addRecord(std::move(Record12));
284
285 Writer.addRecord(std::move(Record2));
286 Writer.addRecord(std::move(Record3));
287 Writer.addRecord(std::move(Record4));
288 Writer.addRecord(std::move(Record5));
289 Writer.addRecord(std::move(Record6));
290 auto Profile = Writer.writeBuffer();
291 readProfile(std::move(Profile));
292
293 ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
294 ASSERT_TRUE(NoError(R.getError()));
295 ASSERT_EQ(5U, R.get().getNumValueSites(IPVK_IndirectCallTarget));
296 ASSERT_EQ(4U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
297 ASSERT_EQ(0U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
298 ASSERT_EQ(4U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
299 ASSERT_EQ(1U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
300 ASSERT_EQ(3U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 4));
301
302 std::unique_ptr<InstrProfValueData[]> VD =
303 R.get().getValueForSite(IPVK_IndirectCallTarget, 0);
Xinliang David Li2004f002015-11-02 05:08:23 +0000304 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee2"));
305 ASSERT_EQ(7U, VD[0].Count);
306 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee3"));
307 ASSERT_EQ(6U, VD[1].Count);
308 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee4"));
309 ASSERT_EQ(4U, VD[2].Count);
310 ASSERT_EQ(StringRef((const char *)VD[3].Value, 7), StringRef("callee1"));
311 ASSERT_EQ(1U, VD[3].Count);
312
313 std::unique_ptr<InstrProfValueData[]> VD_2(
314 R.get().getValueForSite(IPVK_IndirectCallTarget, 2));
Xinliang David Li2004f002015-11-02 05:08:23 +0000315 ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee3"));
316 ASSERT_EQ(6U, VD_2[0].Count);
317 ASSERT_EQ(StringRef((const char *)VD_2[1].Value, 7), StringRef("callee4"));
318 ASSERT_EQ(4U, VD_2[1].Count);
319 ASSERT_EQ(StringRef((const char *)VD_2[2].Value, 7), StringRef("callee2"));
320 ASSERT_EQ(3U, VD_2[2].Count);
321 ASSERT_EQ(StringRef((const char *)VD_2[3].Value, 7), StringRef("callee1"));
322 ASSERT_EQ(1U, VD_2[3].Count);
323
324 std::unique_ptr<InstrProfValueData[]> VD_3(
325 R.get().getValueForSite(IPVK_IndirectCallTarget, 3));
326 ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee1"));
327 ASSERT_EQ(1U, VD_3[0].Count);
328
329 std::unique_ptr<InstrProfValueData[]> VD_4(
330 R.get().getValueForSite(IPVK_IndirectCallTarget, 4));
Xinliang David Li2004f002015-11-02 05:08:23 +0000331 ASSERT_EQ(StringRef((const char *)VD_4[0].Value, 7), StringRef("callee3"));
332 ASSERT_EQ(6U, VD_4[0].Count);
333 ASSERT_EQ(StringRef((const char *)VD_4[1].Value, 7), StringRef("callee2"));
334 ASSERT_EQ(4U, VD_4[1].Count);
335 ASSERT_EQ(StringRef((const char *)VD_4[2].Value, 7), StringRef("callee1"));
336 ASSERT_EQ(2U, VD_4[2].Count);
337}
338
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000339TEST_F(InstrProfTest, get_icall_data_merge1_saturation) {
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000340 static const char bar[] = "bar";
341
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000342 const uint64_t Max = std::numeric_limits<uint64_t>::max();
343
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000344 InstrProfRecord Record1("foo", 0x1234, {1});
345 auto Result1 = Writer.addRecord(std::move(Record1));
346 ASSERT_EQ(Result1, instrprof_error::success);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000347
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000348 // Verify counter overflow.
349 InstrProfRecord Record2("foo", 0x1234, {Max});
350 auto Result2 = Writer.addRecord(std::move(Record2));
351 ASSERT_EQ(Result2, instrprof_error::counter_overflow);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000352
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000353 InstrProfRecord Record3(bar, 0x9012, {8});
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000354 auto Result3 = Writer.addRecord(std::move(Record3));
355 ASSERT_EQ(Result3, instrprof_error::success);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000356
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000357 InstrProfRecord Record4("baz", 0x5678, {3, 4});
358 Record4.reserveSites(IPVK_IndirectCallTarget, 1);
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000359 InstrProfValueData VD4[] = {{uint64_t(bar), 1}};
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000360 Record4.addValueData(IPVK_IndirectCallTarget, 0, VD4, 1, nullptr);
361 auto Result4 = Writer.addRecord(std::move(Record4));
362 ASSERT_EQ(Result4, instrprof_error::success);
363
364 // Verify value data counter overflow.
365 InstrProfRecord Record5("baz", 0x5678, {5, 6});
366 Record5.reserveSites(IPVK_IndirectCallTarget, 1);
NAKAMURA Takumi7345ac02015-12-27 06:18:57 +0000367 InstrProfValueData VD5[] = {{uint64_t(bar), Max}};
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000368 Record5.addValueData(IPVK_IndirectCallTarget, 0, VD5, 1, nullptr);
369 auto Result5 = Writer.addRecord(std::move(Record5));
370 ASSERT_EQ(Result5, instrprof_error::counter_overflow);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000371
Xinliang David Li876c2022016-01-22 05:48:40 +0000372 ASSERT_EQ(support::little, InstrProfWriter::getValueProfDataEndianness());
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000373 auto Profile = Writer.writeBuffer();
374 readProfile(std::move(Profile));
375
376 // Verify saturation of counts.
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000377 ErrorOr<InstrProfRecord> ReadRecord1 =
378 Reader->getInstrProfRecord("foo", 0x1234);
379 ASSERT_TRUE(NoError(ReadRecord1.getError()));
380 ASSERT_EQ(Max, ReadRecord1.get().Counts[0]);
Nathan Slingerlandaa5702d2015-12-02 18:19:24 +0000381
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000382 ErrorOr<InstrProfRecord> ReadRecord2 =
383 Reader->getInstrProfRecord("baz", 0x5678);
384 ASSERT_EQ(1U, ReadRecord2.get().getNumValueSites(IPVK_IndirectCallTarget));
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000385 std::unique_ptr<InstrProfValueData[]> VD =
Nathan Slingerland48dd0802015-12-16 21:45:43 +0000386 ReadRecord2.get().getValueForSite(IPVK_IndirectCallTarget, 0);
387 ASSERT_EQ(StringRef("bar"), StringRef((const char *)VD[0].Value, 3));
388 ASSERT_EQ(Max, VD[0].Count);
Daniel Sandersbe9db3c2015-11-20 13:13:53 +0000389}
390
Xinliang David Li872df222016-01-08 06:54:27 +0000391// This test tests that when there are too many values
392// for a given site, the merged results are properly
393// truncated.
394TEST_F(InstrProfTest, get_icall_data_merge_site_trunc) {
395 static const char caller[] = "caller";
396
397 InstrProfRecord Record11(caller, 0x1234, {1, 2});
398 InstrProfRecord Record12(caller, 0x1234, {1, 2});
399
400 // 2 value sites.
401 Record11.reserveSites(IPVK_IndirectCallTarget, 2);
402 InstrProfValueData VD0[255];
403 for (int I = 0; I < 255; I++) {
404 VD0[I].Value = 2 * I;
405 VD0[I].Count = 2 * I + 1000;
406 }
407
408 Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 255, nullptr);
409 Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
410
411 Record12.reserveSites(IPVK_IndirectCallTarget, 2);
412 InstrProfValueData VD1[255];
413 for (int I = 0; I < 255; I++) {
414 VD1[I].Value = 2 * I + 1;
415 VD1[I].Count = 2 * I + 1001;
416 }
417
418 Record12.addValueData(IPVK_IndirectCallTarget, 0, VD1, 255, nullptr);
419 Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
420
Xinliang David Li876c2022016-01-22 05:48:40 +0000421 ASSERT_EQ(support::little, InstrProfWriter::getValueProfDataEndianness());
Xinliang David Li872df222016-01-08 06:54:27 +0000422 Writer.addRecord(std::move(Record11));
423 // Merge profile data.
424 Writer.addRecord(std::move(Record12));
425
426 auto Profile = Writer.writeBuffer();
427 readProfile(std::move(Profile));
428
429 ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
430 ASSERT_TRUE(NoError(R.getError()));
431 std::unique_ptr<InstrProfValueData[]> VD(
432 R.get().getValueForSite(IPVK_IndirectCallTarget, 0));
433 ASSERT_EQ(2U, R.get().getNumValueSites(IPVK_IndirectCallTarget));
434 ASSERT_EQ(255U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
NAKAMURA Takumi249edf32016-01-08 07:58:20 +0000435 for (unsigned I = 0; I < 255; I++) {
Xinliang David Li872df222016-01-08 06:54:27 +0000436 ASSERT_EQ(VD[I].Value, 509 - I);
437 ASSERT_EQ(VD[I].Count, 1509 - I);
438 }
439}
440
Xinliang David Lied966772015-11-25 23:31:18 +0000441// Synthesize runtime value profile data.
442ValueProfNode Site1Values[5] = {{{uint64_t("callee1"), 400}, &Site1Values[1]},
443 {{uint64_t("callee2"), 1000}, &Site1Values[2]},
444 {{uint64_t("callee3"), 500}, &Site1Values[3]},
445 {{uint64_t("callee4"), 300}, &Site1Values[4]},
446 {{uint64_t("callee5"), 100}, 0}};
447
448ValueProfNode Site2Values[4] = {{{uint64_t("callee5"), 800}, &Site2Values[1]},
449 {{uint64_t("callee3"), 1000}, &Site2Values[2]},
450 {{uint64_t("callee2"), 2500}, &Site2Values[3]},
451 {{uint64_t("callee1"), 1300}, 0}};
452
453ValueProfNode Site3Values[3] = {{{uint64_t("callee6"), 800}, &Site3Values[1]},
454 {{uint64_t("callee3"), 1000}, &Site3Values[2]},
455 {{uint64_t("callee4"), 5500}, 0}};
456
457ValueProfNode Site4Values[2] = {{{uint64_t("callee2"), 1800}, &Site4Values[1]},
458 {{uint64_t("callee3"), 2000}, 0}};
459
460static ValueProfNode *ValueProfNodes[5] = {&Site1Values[0], &Site2Values[0],
461 &Site3Values[0], &Site4Values[0], 0};
462static uint16_t NumValueSites[IPVK_Last + 1] = {5};
463TEST_F(InstrProfTest, runtime_value_prof_data_read_write) {
464 ValueProfRuntimeRecord RTRecord;
465 initializeValueProfRuntimeRecord(&RTRecord, &NumValueSites[0],
466 &ValueProfNodes[0]);
467
Xinliang David Li0e6a36e2015-12-01 19:47:32 +0000468 ValueProfData *VPData = serializeValueProfDataFromRT(&RTRecord, nullptr);
Xinliang David Lied966772015-11-25 23:31:18 +0000469
470 InstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2});
471
472 VPData->deserializeTo(Record, 0);
473
474 // Now read data from Record and sanity check the data
475 ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget));
476 ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
477 ASSERT_EQ(4U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
478 ASSERT_EQ(3U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
479 ASSERT_EQ(2U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
480 ASSERT_EQ(0U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 4));
481
482 auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
483 return VD1.Count > VD2.Count;
484 };
485 std::unique_ptr<InstrProfValueData[]> VD_0(
486 Record.getValueForSite(IPVK_IndirectCallTarget, 0));
487 std::sort(&VD_0[0], &VD_0[5], Cmp);
488 ASSERT_EQ(StringRef((const char *)VD_0[0].Value, 7), StringRef("callee2"));
489 ASSERT_EQ(1000U, VD_0[0].Count);
490 ASSERT_EQ(StringRef((const char *)VD_0[1].Value, 7), StringRef("callee3"));
491 ASSERT_EQ(500U, VD_0[1].Count);
492 ASSERT_EQ(StringRef((const char *)VD_0[2].Value, 7), StringRef("callee1"));
493 ASSERT_EQ(400U, VD_0[2].Count);
494 ASSERT_EQ(StringRef((const char *)VD_0[3].Value, 7), StringRef("callee4"));
495 ASSERT_EQ(300U, VD_0[3].Count);
496 ASSERT_EQ(StringRef((const char *)VD_0[4].Value, 7), StringRef("callee5"));
497 ASSERT_EQ(100U, VD_0[4].Count);
498
499 std::unique_ptr<InstrProfValueData[]> VD_1(
500 Record.getValueForSite(IPVK_IndirectCallTarget, 1));
501 std::sort(&VD_1[0], &VD_1[4], Cmp);
502 ASSERT_EQ(StringRef((const char *)VD_1[0].Value, 7), StringRef("callee2"));
503 ASSERT_EQ(2500U, VD_1[0].Count);
504 ASSERT_EQ(StringRef((const char *)VD_1[1].Value, 7), StringRef("callee1"));
505 ASSERT_EQ(1300U, VD_1[1].Count);
506 ASSERT_EQ(StringRef((const char *)VD_1[2].Value, 7), StringRef("callee3"));
507 ASSERT_EQ(1000U, VD_1[2].Count);
508 ASSERT_EQ(StringRef((const char *)VD_1[3].Value, 7), StringRef("callee5"));
509 ASSERT_EQ(800U, VD_1[3].Count);
510
511 std::unique_ptr<InstrProfValueData[]> VD_2(
512 Record.getValueForSite(IPVK_IndirectCallTarget, 2));
513 std::sort(&VD_2[0], &VD_2[3], Cmp);
514 ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee4"));
515 ASSERT_EQ(5500U, VD_2[0].Count);
516 ASSERT_EQ(StringRef((const char *)VD_2[1].Value, 7), StringRef("callee3"));
517 ASSERT_EQ(1000U, VD_2[1].Count);
518 ASSERT_EQ(StringRef((const char *)VD_2[2].Value, 7), StringRef("callee6"));
519 ASSERT_EQ(800U, VD_2[2].Count);
520
521 std::unique_ptr<InstrProfValueData[]> VD_3(
522 Record.getValueForSite(IPVK_IndirectCallTarget, 3));
523 std::sort(&VD_3[0], &VD_3[2], Cmp);
524 ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee3"));
525 ASSERT_EQ(2000U, VD_3[0].Count);
526 ASSERT_EQ(StringRef((const char *)VD_3[1].Value, 7), StringRef("callee2"));
527 ASSERT_EQ(1800U, VD_3[1].Count);
528
529 finalizeValueProfRuntimeRecord(&RTRecord);
530 free(VPData);
531}
532
Justin Bogner2b6c5372015-02-18 01:58:17 +0000533TEST_F(InstrProfTest, get_max_function_count) {
Justin Bogner9e9a0572015-09-29 22:13:58 +0000534 InstrProfRecord Record1("foo", 0x1234, {1ULL << 31, 2});
535 InstrProfRecord Record2("bar", 0, {1ULL << 63});
536 InstrProfRecord Record3("baz", 0x5678, {0, 0, 0, 0});
537 Writer.addRecord(std::move(Record1));
538 Writer.addRecord(std::move(Record2));
539 Writer.addRecord(std::move(Record3));
Justin Bogner2b6c5372015-02-18 01:58:17 +0000540 auto Profile = Writer.writeBuffer();
541 readProfile(std::move(Profile));
542
543 ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount());
544}
545
Nathan Slingerland7f5b47d2015-12-15 17:37:09 +0000546TEST_F(InstrProfTest, get_weighted_function_counts) {
547 InstrProfRecord Record1("foo", 0x1234, {1, 2});
548 InstrProfRecord Record2("foo", 0x1235, {3, 4});
549 Writer.addRecord(std::move(Record1), 3);
550 Writer.addRecord(std::move(Record2), 5);
551 auto Profile = Writer.writeBuffer();
552 readProfile(std::move(Profile));
553
554 std::vector<uint64_t> Counts;
555 ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1234, Counts)));
556 ASSERT_EQ(2U, Counts.size());
557 ASSERT_EQ(3U, Counts[0]);
558 ASSERT_EQ(6U, Counts[1]);
559
560 ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1235, Counts)));
561 ASSERT_EQ(2U, Counts.size());
562 ASSERT_EQ(15U, Counts[0]);
563 ASSERT_EQ(20U, Counts[1]);
564}
565
Xinliang David Li2ee5c4d2015-12-19 07:44:57 +0000566TEST_F(InstrProfTest, instr_prof_symtab_test) {
567 std::vector<StringRef> FuncNames;
568 FuncNames.push_back("func1");
569 FuncNames.push_back("func2");
570 FuncNames.push_back("func3");
571 FuncNames.push_back("bar1");
572 FuncNames.push_back("bar2");
573 FuncNames.push_back("bar3");
574 InstrProfSymtab Symtab;
575 Symtab.create(FuncNames);
576 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
577 ASSERT_EQ(StringRef("func1"), R);
578 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
579 ASSERT_EQ(StringRef("func2"), R);
580 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
581 ASSERT_EQ(StringRef("func3"), R);
582 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
583 ASSERT_EQ(StringRef("bar1"), R);
584 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
585 ASSERT_EQ(StringRef("bar2"), R);
586 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
587 ASSERT_EQ(StringRef("bar3"), R);
Xinliang David Lic96d3d12015-12-19 18:20:09 +0000588
589 // Now incrementally update the symtab
590 Symtab.addFuncName("blah_1");
591 Symtab.addFuncName("blah_2");
592 Symtab.addFuncName("blah_3");
593 // Finalize it
594 Symtab.finalizeSymtab();
595
596 // Check again
597 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_1"));
598 ASSERT_EQ(StringRef("blah_1"), R);
599 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_2"));
600 ASSERT_EQ(StringRef("blah_2"), R);
601 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_3"));
602 ASSERT_EQ(StringRef("blah_3"), R);
603 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
604 ASSERT_EQ(StringRef("func1"), R);
605 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
606 ASSERT_EQ(StringRef("func2"), R);
607 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
608 ASSERT_EQ(StringRef("func3"), R);
609 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
610 ASSERT_EQ(StringRef("bar1"), R);
611 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
612 ASSERT_EQ(StringRef("bar2"), R);
613 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
614 ASSERT_EQ(StringRef("bar3"), R);
Xinliang David Li2ee5c4d2015-12-19 07:44:57 +0000615}
616
Xinliang David Li59411db2016-01-20 01:26:34 +0000617TEST_F(InstrProfTest, instr_prof_symtab_module_test) {
618 LLVMContext Ctx;
619 std::unique_ptr<Module> M = llvm::make_unique<Module>("MyModule.cpp", Ctx);
620 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
621 /*isVarArg=*/false);
622 Function::Create(FTy, Function::ExternalLinkage, "Gfoo", M.get());
623 Function::Create(FTy, Function::ExternalLinkage, "Gblah", M.get());
624 Function::Create(FTy, Function::ExternalLinkage, "Gbar", M.get());
625 Function::Create(FTy, Function::InternalLinkage, "Ifoo", M.get());
626 Function::Create(FTy, Function::InternalLinkage, "Iblah", M.get());
627 Function::Create(FTy, Function::InternalLinkage, "Ibar", M.get());
628 Function::Create(FTy, Function::PrivateLinkage, "Pfoo", M.get());
629 Function::Create(FTy, Function::PrivateLinkage, "Pblah", M.get());
630 Function::Create(FTy, Function::PrivateLinkage, "Pbar", M.get());
631 Function::Create(FTy, Function::WeakODRLinkage, "Wfoo", M.get());
632 Function::Create(FTy, Function::WeakODRLinkage, "Wblah", M.get());
633 Function::Create(FTy, Function::WeakODRLinkage, "Wbar", M.get());
634
635 InstrProfSymtab ProfSymtab;
636 ProfSymtab.create(*(M.get()));
637
638 StringRef Funcs[] = {"Gfoo", "Gblah", "Gbar", "Ifoo", "Iblah", "Ibar",
639 "Pfoo", "Pblah", "Pbar", "Wfoo", "Wblah", "Wbar"};
640
641 for (unsigned I = 0; I < sizeof(Funcs) / sizeof(*Funcs); I++) {
642 Function *F = M->getFunction(Funcs[I]);
643 ASSERT_TRUE(F != NULL);
Xinliang David Lida656fe2016-01-20 02:49:53 +0000644 std::string PGOName = getPGOFuncName(*F);
Xinliang David Li3865fdc2016-01-22 18:13:34 +0000645 uint64_t Key = IndexedInstrProf::ComputeHash(PGOName);
Xinliang David Lida656fe2016-01-20 02:49:53 +0000646 ASSERT_EQ(StringRef(PGOName),
Xinliang David Li3865fdc2016-01-22 18:13:34 +0000647 ProfSymtab.getFuncName(Key));
648 ASSERT_EQ(StringRef(Funcs[I]), ProfSymtab.getOrigFuncName(Key));
Xinliang David Li59411db2016-01-20 01:26:34 +0000649 }
650}
651
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000652TEST_F(InstrProfTest, instr_prof_symtab_compression_test) {
653 std::vector<std::string> FuncNames1;
654 std::vector<std::string> FuncNames2;
655 for (int I = 0; I < 10 * 1024; I++) {
656 std::string str;
657 raw_string_ostream OS(str);
658 OS << "func_" << I;
659 FuncNames1.push_back(OS.str());
660 str.clear();
661 OS << "fooooooooooooooo_" << I;
662 FuncNames1.push_back(OS.str());
663 str.clear();
664 OS << "BAR_" << I;
665 FuncNames2.push_back(OS.str());
666 str.clear();
667 OS << "BlahblahBlahblahBar_" << I;
668 FuncNames2.push_back(OS.str());
669 }
670
671 for (int Padding = 0; Padding < 10; Padding++) {
672 for (int DoCompression = 0; DoCompression < 2; DoCompression++) {
673 // Compressing:
674 std::string FuncNameStrings1;
675 collectPGOFuncNameStrings(FuncNames1,
676 (DoCompression != 0 && zlib::isAvailable()),
677 FuncNameStrings1);
678
679 // Compressing:
680 std::string FuncNameStrings2;
681 collectPGOFuncNameStrings(FuncNames2,
682 (DoCompression != 0 && zlib::isAvailable()),
683 FuncNameStrings2);
684
685 // Join with paddings:
686 std::string FuncNameStrings = FuncNameStrings1;
687 for (int P = 0; P < Padding; P++) {
688 FuncNameStrings.push_back('\0');
689 }
690 FuncNameStrings += FuncNameStrings2;
691
Xinliang David Li8dec8b12016-01-04 23:59:14 +0000692 // Now decompress:
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000693 InstrProfSymtab Symtab;
694 Symtab.create(StringRef(FuncNameStrings));
695
Xinliang David Li8dec8b12016-01-04 23:59:14 +0000696 // Now do the checks:
697 // First sampling some data points:
698 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[0]));
699 ASSERT_EQ(StringRef("func_0"), R);
700 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[1]));
701 ASSERT_EQ(StringRef("fooooooooooooooo_0"), R);
702 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[998]));
703 ASSERT_EQ(StringRef("func_499"), R);
704 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[999]));
705 ASSERT_EQ(StringRef("fooooooooooooooo_499"), R);
706 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames2[100]));
707 ASSERT_EQ(StringRef("BAR_50"), R);
708 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames2[101]));
709 ASSERT_EQ(StringRef("BlahblahBlahblahBar_50"), R);
Xinliang David Lie413f1a2015-12-31 07:57:16 +0000710 for (int I = 0; I < 10 * 1024; I++) {
711 std::string N[4];
712 N[0] = FuncNames1[2 * I];
713 N[1] = FuncNames1[2 * I + 1];
714 N[2] = FuncNames2[2 * I];
715 N[3] = FuncNames2[2 * I + 1];
716 for (int J = 0; J < 4; J++) {
717 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(N[J]));
718 ASSERT_EQ(StringRef(N[J]), R);
719 }
720 }
721 }
722 }
723}
724
Xinliang David Li876c2022016-01-22 05:48:40 +0000725// Keep this the last test case as it sets the VP data endianness
726TEST_F(InstrProfTest, get_icall_data_read_write_big_endian) {
727 InstrProfRecord Record1("caller", 0x1234, {1, 2});
728 InstrProfRecord Record2("callee1", 0x1235, {3, 4});
729 InstrProfRecord Record3("callee2", 0x1235, {3, 4});
730 InstrProfRecord Record4("callee3", 0x1235, {3, 4});
731
732 // 4 value sites.
733 Record1.reserveSites(IPVK_IndirectCallTarget, 4);
734 InstrProfValueData VD0[] = {{(uint64_t) "callee1", 1},
735 {(uint64_t) "callee2", 2},
736 {(uint64_t) "callee3", 3}};
737 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
738 // No value profile data at the second site.
739 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
740 InstrProfValueData VD2[] = {{(uint64_t) "callee1", 1},
741 {(uint64_t) "callee2", 2}};
742 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
743 InstrProfValueData VD3[] = {{(uint64_t) "callee1", 1}};
744 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
745
746 Writer.addRecord(std::move(Record1));
747 Writer.addRecord(std::move(Record2));
748 Writer.addRecord(std::move(Record3));
749 Writer.addRecord(std::move(Record4));
750
751 // Set big endian output.
752 const char *args[] = {"InstrProfTest", "-write-vp-data-in-big"};
753 cl::ParseCommandLineOptions(sizeof(args) / sizeof(const char *), args);
754 ASSERT_EQ(support::big, InstrProfWriter::getValueProfDataEndianness());
755
756 auto Profile = Writer.writeBuffer();
757 readProfile(std::move(Profile));
758
759 // Set big endian input.
760 Reader->setValueProfDataEndianness(support::big);
761
762 ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
763 ASSERT_TRUE(NoError(R.getError()));
764 ASSERT_EQ(4U, R.get().getNumValueSites(IPVK_IndirectCallTarget));
765 ASSERT_EQ(3U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
766 ASSERT_EQ(0U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
767 ASSERT_EQ(2U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
768 ASSERT_EQ(1U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
769
770 std::unique_ptr<InstrProfValueData[]> VD =
771 R.get().getValueForSite(IPVK_IndirectCallTarget, 0);
772 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
773 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
774 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
775}
776
Justin Bogner2b6c5372015-02-18 01:58:17 +0000777} // end anonymous namespace