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