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