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 static const auto Err = [](Error E) { 68 consumeError(std::move(E)); 69 FAIL(); 70 }; 71 72 TEST_P(MaybeSparseInstrProfTest, write_and_read_one_function) { 73 Writer.addRecord({"foo", 0x1234, {1, 2, 3, 4}}, Err); 74 auto Profile = Writer.writeBuffer(); 75 readProfile(std::move(Profile)); 76 77 auto I = Reader->begin(), E = Reader->end(); 78 ASSERT_TRUE(I != E); 79 ASSERT_EQ(StringRef("foo"), I->Name); 80 ASSERT_EQ(0x1234U, I->Hash); 81 ASSERT_EQ(4U, I->Counts.size()); 82 ASSERT_EQ(1U, I->Counts[0]); 83 ASSERT_EQ(2U, I->Counts[1]); 84 ASSERT_EQ(3U, I->Counts[2]); 85 ASSERT_EQ(4U, I->Counts[3]); 86 ASSERT_TRUE(++I == E); 87 } 88 89 TEST_P(MaybeSparseInstrProfTest, get_instr_prof_record) { 90 Writer.addRecord({"foo", 0x1234, {1, 2}}, Err); 91 Writer.addRecord({"foo", 0x1235, {3, 4}}, Err); 92 auto Profile = Writer.writeBuffer(); 93 readProfile(std::move(Profile)); 94 95 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("foo", 0x1234); 96 EXPECT_THAT_ERROR(R.takeError(), Succeeded()); 97 ASSERT_EQ(2U, R->Counts.size()); 98 ASSERT_EQ(1U, R->Counts[0]); 99 ASSERT_EQ(2U, R->Counts[1]); 100 101 R = Reader->getInstrProfRecord("foo", 0x1235); 102 EXPECT_THAT_ERROR(R.takeError(), Succeeded()); 103 ASSERT_EQ(2U, R->Counts.size()); 104 ASSERT_EQ(3U, R->Counts[0]); 105 ASSERT_EQ(4U, R->Counts[1]); 106 107 R = Reader->getInstrProfRecord("foo", 0x5678); 108 ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, R.takeError())); 109 110 R = Reader->getInstrProfRecord("bar", 0x1234); 111 ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, R.takeError())); 112 } 113 114 TEST_P(MaybeSparseInstrProfTest, get_function_counts) { 115 Writer.addRecord({"foo", 0x1234, {1, 2}}, Err); 116 Writer.addRecord({"foo", 0x1235, {3, 4}}, Err); 117 auto Profile = Writer.writeBuffer(); 118 readProfile(std::move(Profile)); 119 120 std::vector<uint64_t> Counts; 121 EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1234, Counts), 122 Succeeded()); 123 ASSERT_EQ(2U, Counts.size()); 124 ASSERT_EQ(1U, Counts[0]); 125 ASSERT_EQ(2U, Counts[1]); 126 127 EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1235, Counts), 128 Succeeded()); 129 ASSERT_EQ(2U, Counts.size()); 130 ASSERT_EQ(3U, Counts[0]); 131 ASSERT_EQ(4U, Counts[1]); 132 133 Error E1 = Reader->getFunctionCounts("foo", 0x5678, Counts); 134 ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, std::move(E1))); 135 136 Error E2 = Reader->getFunctionCounts("bar", 0x1234, Counts); 137 ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, std::move(E2))); 138 } 139 140 // Profile data is copied from general.proftext 141 TEST_F(InstrProfTest, get_profile_summary) { 142 Writer.addRecord({"func1", 0x1234, {97531}}, Err); 143 Writer.addRecord({"func2", 0x1234, {0, 0}}, Err); 144 Writer.addRecord( 145 {"func3", 146 0x1234, 147 {2305843009213693952, 1152921504606846976, 576460752303423488, 148 288230376151711744, 144115188075855872, 72057594037927936}}, 149 Err); 150 Writer.addRecord({"func4", 0x1234, {0}}, Err); 151 auto Profile = Writer.writeBuffer(); 152 readProfile(std::move(Profile)); 153 154 auto VerifySummary = [](ProfileSummary &IPS) mutable { 155 ASSERT_EQ(ProfileSummary::PSK_Instr, IPS.getKind()); 156 ASSERT_EQ(2305843009213693952U, IPS.getMaxFunctionCount()); 157 ASSERT_EQ(2305843009213693952U, IPS.getMaxCount()); 158 ASSERT_EQ(10U, IPS.getNumCounts()); 159 ASSERT_EQ(4539628424389557499U, IPS.getTotalCount()); 160 std::vector<ProfileSummaryEntry> &Details = IPS.getDetailedSummary(); 161 uint32_t Cutoff = 800000; 162 auto Predicate = [&Cutoff](const ProfileSummaryEntry &PE) { 163 return PE.Cutoff == Cutoff; 164 }; 165 auto EightyPerc = find_if(Details, Predicate); 166 Cutoff = 900000; 167 auto NinetyPerc = find_if(Details, Predicate); 168 Cutoff = 950000; 169 auto NinetyFivePerc = find_if(Details, Predicate); 170 Cutoff = 990000; 171 auto NinetyNinePerc = find_if(Details, Predicate); 172 ASSERT_EQ(576460752303423488U, EightyPerc->MinCount); 173 ASSERT_EQ(288230376151711744U, NinetyPerc->MinCount); 174 ASSERT_EQ(288230376151711744U, NinetyFivePerc->MinCount); 175 ASSERT_EQ(72057594037927936U, NinetyNinePerc->MinCount); 176 }; 177 ProfileSummary &PS = Reader->getSummary(); 178 VerifySummary(PS); 179 180 // Test that conversion of summary to and from Metadata works. 181 LLVMContext Context; 182 Metadata *MD = PS.getMD(Context); 183 ASSERT_TRUE(MD); 184 ProfileSummary *PSFromMD = ProfileSummary::getFromMD(MD); 185 ASSERT_TRUE(PSFromMD); 186 VerifySummary(*PSFromMD); 187 delete PSFromMD; 188 189 // Test that summary can be attached to and read back from module. 190 Module M("my_module", Context); 191 M.setProfileSummary(MD); 192 MD = M.getProfileSummary(); 193 ASSERT_TRUE(MD); 194 PSFromMD = ProfileSummary::getFromMD(MD); 195 ASSERT_TRUE(PSFromMD); 196 VerifySummary(*PSFromMD); 197 delete PSFromMD; 198 } 199 200 TEST_F(InstrProfTest, test_writer_merge) { 201 Writer.addRecord({"func1", 0x1234, {42}}, Err); 202 203 InstrProfWriter Writer2; 204 Writer2.addRecord({"func2", 0x1234, {0, 0}}, Err); 205 206 Writer.mergeRecordsFromWriter(std::move(Writer2), Err); 207 208 auto Profile = Writer.writeBuffer(); 209 readProfile(std::move(Profile)); 210 211 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("func1", 0x1234); 212 EXPECT_THAT_ERROR(R.takeError(), Succeeded()); 213 ASSERT_EQ(1U, R->Counts.size()); 214 ASSERT_EQ(42U, R->Counts[0]); 215 216 R = Reader->getInstrProfRecord("func2", 0x1234); 217 EXPECT_THAT_ERROR(R.takeError(), Succeeded()); 218 ASSERT_EQ(2U, R->Counts.size()); 219 ASSERT_EQ(0U, R->Counts[0]); 220 ASSERT_EQ(0U, R->Counts[1]); 221 } 222 223 static const char callee1[] = "callee1"; 224 static const char callee2[] = "callee2"; 225 static const char callee3[] = "callee3"; 226 static const char callee4[] = "callee4"; 227 static const char callee5[] = "callee5"; 228 static const char callee6[] = "callee6"; 229 230 TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write) { 231 NamedInstrProfRecord Record1("caller", 0x1234, {1, 2}); 232 233 // 4 value sites. 234 Record1.reserveSites(IPVK_IndirectCallTarget, 4); 235 InstrProfValueData VD0[] = { 236 {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}}; 237 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr); 238 // No value profile data at the second site. 239 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr); 240 InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}}; 241 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr); 242 InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}}; 243 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr); 244 245 Writer.addRecord(std::move(Record1), Err); 246 Writer.addRecord({"callee1", 0x1235, {3, 4}}, Err); 247 Writer.addRecord({"callee2", 0x1235, {3, 4}}, Err); 248 Writer.addRecord({"callee3", 0x1235, {3, 4}}, Err); 249 auto Profile = Writer.writeBuffer(); 250 readProfile(std::move(Profile)); 251 252 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234); 253 EXPECT_THAT_ERROR(R.takeError(), Succeeded()); 254 ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget)); 255 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); 256 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1)); 257 ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2)); 258 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3)); 259 260 uint64_t TotalC; 261 std::unique_ptr<InstrProfValueData[]> VD = 262 R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC); 263 264 ASSERT_EQ(3U, VD[0].Count); 265 ASSERT_EQ(2U, VD[1].Count); 266 ASSERT_EQ(1U, VD[2].Count); 267 ASSERT_EQ(6U, TotalC); 268 269 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3")); 270 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2")); 271 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1")); 272 } 273 274 TEST_P(MaybeSparseInstrProfTest, annotate_vp_data) { 275 NamedInstrProfRecord Record("caller", 0x1234, {1, 2}); 276 Record.reserveSites(IPVK_IndirectCallTarget, 1); 277 InstrProfValueData VD0[] = {{1000, 1}, {2000, 2}, {3000, 3}, {5000, 5}, 278 {4000, 4}, {6000, 6}}; 279 Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 6, nullptr); 280 Writer.addRecord(std::move(Record), Err); 281 auto Profile = Writer.writeBuffer(); 282 readProfile(std::move(Profile)); 283 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234); 284 EXPECT_THAT_ERROR(R.takeError(), Succeeded()); 285 286 LLVMContext Ctx; 287 std::unique_ptr<Module> M(new Module("MyModule", Ctx)); 288 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx), 289 /*isVarArg=*/false); 290 Function *F = 291 Function::Create(FTy, Function::ExternalLinkage, "caller", M.get()); 292 BasicBlock *BB = BasicBlock::Create(Ctx, "", F); 293 294 IRBuilder<> Builder(BB); 295 BasicBlock *TBB = BasicBlock::Create(Ctx, "", F); 296 BasicBlock *FBB = BasicBlock::Create(Ctx, "", F); 297 298 // Use branch instruction to annotate with value profile data for simplicity 299 Instruction *Inst = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB); 300 Instruction *Inst2 = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB); 301 annotateValueSite(*M, *Inst, R.get(), IPVK_IndirectCallTarget, 0); 302 303 InstrProfValueData ValueData[5]; 304 uint32_t N; 305 uint64_t T; 306 bool Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5, 307 ValueData, N, T); 308 ASSERT_TRUE(Res); 309 ASSERT_EQ(3U, N); 310 ASSERT_EQ(21U, T); 311 // The result should be sorted already: 312 ASSERT_EQ(6000U, ValueData[0].Value); 313 ASSERT_EQ(6U, ValueData[0].Count); 314 ASSERT_EQ(5000U, ValueData[1].Value); 315 ASSERT_EQ(5U, ValueData[1].Count); 316 ASSERT_EQ(4000U, ValueData[2].Value); 317 ASSERT_EQ(4U, ValueData[2].Count); 318 Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 1, ValueData, 319 N, T); 320 ASSERT_TRUE(Res); 321 ASSERT_EQ(1U, N); 322 ASSERT_EQ(21U, T); 323 324 Res = getValueProfDataFromInst(*Inst2, IPVK_IndirectCallTarget, 5, ValueData, 325 N, T); 326 ASSERT_FALSE(Res); 327 328 // Remove the MD_prof metadata 329 Inst->setMetadata(LLVMContext::MD_prof, 0); 330 // Annotate 5 records this time. 331 annotateValueSite(*M, *Inst, R.get(), IPVK_IndirectCallTarget, 0, 5); 332 Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5, 333 ValueData, N, T); 334 ASSERT_TRUE(Res); 335 ASSERT_EQ(5U, N); 336 ASSERT_EQ(21U, T); 337 ASSERT_EQ(6000U, ValueData[0].Value); 338 ASSERT_EQ(6U, ValueData[0].Count); 339 ASSERT_EQ(5000U, ValueData[1].Value); 340 ASSERT_EQ(5U, ValueData[1].Count); 341 ASSERT_EQ(4000U, ValueData[2].Value); 342 ASSERT_EQ(4U, ValueData[2].Count); 343 ASSERT_EQ(3000U, ValueData[3].Value); 344 ASSERT_EQ(3U, ValueData[3].Count); 345 ASSERT_EQ(2000U, ValueData[4].Value); 346 ASSERT_EQ(2U, ValueData[4].Count); 347 348 // Remove the MD_prof metadata 349 Inst->setMetadata(LLVMContext::MD_prof, 0); 350 // Annotate with 4 records. 351 InstrProfValueData VD0Sorted[] = {{1000, 6}, {2000, 5}, {3000, 4}, {4000, 3}, 352 {5000, 2}, {6000, 1}}; 353 annotateValueSite(*M, *Inst, makeArrayRef(VD0Sorted).slice(2), 10, 354 IPVK_IndirectCallTarget, 5); 355 Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5, 356 ValueData, N, T); 357 ASSERT_TRUE(Res); 358 ASSERT_EQ(4U, N); 359 ASSERT_EQ(10U, T); 360 ASSERT_EQ(3000U, ValueData[0].Value); 361 ASSERT_EQ(4U, ValueData[0].Count); 362 ASSERT_EQ(4000U, ValueData[1].Value); 363 ASSERT_EQ(3U, ValueData[1].Count); 364 ASSERT_EQ(5000U, ValueData[2].Value); 365 ASSERT_EQ(2U, ValueData[2].Count); 366 ASSERT_EQ(6000U, ValueData[3].Value); 367 ASSERT_EQ(1U, ValueData[3].Count); 368 } 369 370 TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_with_weight) { 371 NamedInstrProfRecord Record1("caller", 0x1234, {1, 2}); 372 373 // 4 value sites. 374 Record1.reserveSites(IPVK_IndirectCallTarget, 4); 375 InstrProfValueData VD0[] = { 376 {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}}; 377 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr); 378 // No value profile data at the second site. 379 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr); 380 InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}}; 381 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr); 382 InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}}; 383 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr); 384 385 Writer.addRecord(std::move(Record1), 10, Err); 386 Writer.addRecord({"callee1", 0x1235, {3, 4}}, Err); 387 Writer.addRecord({"callee2", 0x1235, {3, 4}}, Err); 388 Writer.addRecord({"callee3", 0x1235, {3, 4}}, Err); 389 auto Profile = Writer.writeBuffer(); 390 readProfile(std::move(Profile)); 391 392 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234); 393 EXPECT_THAT_ERROR(R.takeError(), Succeeded()); 394 ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget)); 395 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); 396 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1)); 397 ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2)); 398 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3)); 399 400 uint64_t TotalC; 401 std::unique_ptr<InstrProfValueData[]> VD = 402 R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC); 403 ASSERT_EQ(30U, VD[0].Count); 404 ASSERT_EQ(20U, VD[1].Count); 405 ASSERT_EQ(10U, VD[2].Count); 406 ASSERT_EQ(60U, TotalC); 407 408 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3")); 409 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2")); 410 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1")); 411 } 412 413 TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_big_endian) { 414 NamedInstrProfRecord Record1("caller", 0x1234, {1, 2}); 415 416 // 4 value sites. 417 Record1.reserveSites(IPVK_IndirectCallTarget, 4); 418 InstrProfValueData VD0[] = { 419 {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}}; 420 Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr); 421 // No value profile data at the second site. 422 Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr); 423 InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}}; 424 Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr); 425 InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}}; 426 Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr); 427 428 Writer.addRecord(std::move(Record1), Err); 429 Writer.addRecord({"callee1", 0x1235, {3, 4}}, Err); 430 Writer.addRecord({"callee2", 0x1235, {3, 4}}, Err); 431 Writer.addRecord({"callee3", 0x1235, {3, 4}}, Err); 432 433 // Set big endian output. 434 Writer.setValueProfDataEndianness(support::big); 435 436 auto Profile = Writer.writeBuffer(); 437 readProfile(std::move(Profile)); 438 439 // Set big endian input. 440 Reader->setValueProfDataEndianness(support::big); 441 442 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234); 443 EXPECT_THAT_ERROR(R.takeError(), Succeeded()); 444 ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget)); 445 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); 446 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1)); 447 ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2)); 448 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3)); 449 450 std::unique_ptr<InstrProfValueData[]> VD = 451 R->getValueForSite(IPVK_IndirectCallTarget, 0); 452 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3")); 453 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2")); 454 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1")); 455 456 // Restore little endian default: 457 Writer.setValueProfDataEndianness(support::little); 458 } 459 460 TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge1) { 461 static const char caller[] = "caller"; 462 NamedInstrProfRecord Record11(caller, 0x1234, {1, 2}); 463 NamedInstrProfRecord Record12(caller, 0x1234, {1, 2}); 464 465 // 5 value sites. 466 Record11.reserveSites(IPVK_IndirectCallTarget, 5); 467 InstrProfValueData VD0[] = {{uint64_t(callee1), 1}, 468 {uint64_t(callee2), 2}, 469 {uint64_t(callee3), 3}, 470 {uint64_t(callee4), 4}}; 471 Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 4, nullptr); 472 473 // No value profile data at the second site. 474 Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr); 475 476 InstrProfValueData VD2[] = { 477 {uint64_t(callee1), 1}, {uint64_t(callee2), 2}, {uint64_t(callee3), 3}}; 478 Record11.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr); 479 480 InstrProfValueData VD3[] = {{uint64_t(callee1), 1}}; 481 Record11.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr); 482 483 InstrProfValueData VD4[] = {{uint64_t(callee1), 1}, 484 {uint64_t(callee2), 2}, 485 {uint64_t(callee3), 3}}; 486 Record11.addValueData(IPVK_IndirectCallTarget, 4, VD4, 3, nullptr); 487 488 // A different record for the same caller. 489 Record12.reserveSites(IPVK_IndirectCallTarget, 5); 490 InstrProfValueData VD02[] = {{uint64_t(callee2), 5}, {uint64_t(callee3), 3}}; 491 Record12.addValueData(IPVK_IndirectCallTarget, 0, VD02, 2, nullptr); 492 493 // No value profile data at the second site. 494 Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr); 495 496 InstrProfValueData VD22[] = { 497 {uint64_t(callee2), 1}, {uint64_t(callee3), 3}, {uint64_t(callee4), 4}}; 498 Record12.addValueData(IPVK_IndirectCallTarget, 2, VD22, 3, nullptr); 499 500 Record12.addValueData(IPVK_IndirectCallTarget, 3, nullptr, 0, nullptr); 501 502 InstrProfValueData VD42[] = {{uint64_t(callee1), 1}, 503 {uint64_t(callee2), 2}, 504 {uint64_t(callee3), 3}}; 505 Record12.addValueData(IPVK_IndirectCallTarget, 4, VD42, 3, nullptr); 506 507 Writer.addRecord(std::move(Record11), Err); 508 // Merge profile data. 509 Writer.addRecord(std::move(Record12), Err); 510 511 Writer.addRecord({callee1, 0x1235, {3, 4}}, Err); 512 Writer.addRecord({callee2, 0x1235, {3, 4}}, Err); 513 Writer.addRecord({callee3, 0x1235, {3, 4}}, Err); 514 Writer.addRecord({callee3, 0x1235, {3, 4}}, Err); 515 Writer.addRecord({callee4, 0x1235, {3, 5}}, Err); 516 auto Profile = Writer.writeBuffer(); 517 readProfile(std::move(Profile)); 518 519 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234); 520 EXPECT_THAT_ERROR(R.takeError(), Succeeded()); 521 ASSERT_EQ(5U, R->getNumValueSites(IPVK_IndirectCallTarget)); 522 ASSERT_EQ(4U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); 523 ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1)); 524 ASSERT_EQ(4U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2)); 525 ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3)); 526 ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 4)); 527 528 std::unique_ptr<InstrProfValueData[]> VD = 529 R->getValueForSite(IPVK_IndirectCallTarget, 0); 530 ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee2")); 531 ASSERT_EQ(7U, VD[0].Count); 532 ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee3")); 533 ASSERT_EQ(6U, VD[1].Count); 534 ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee4")); 535 ASSERT_EQ(4U, VD[2].Count); 536 ASSERT_EQ(StringRef((const char *)VD[3].Value, 7), StringRef("callee1")); 537 ASSERT_EQ(1U, VD[3].Count); 538 539 std::unique_ptr<InstrProfValueData[]> VD_2( 540 R->getValueForSite(IPVK_IndirectCallTarget, 2)); 541 ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee3")); 542 ASSERT_EQ(6U, VD_2[0].Count); 543 ASSERT_EQ(StringRef((const char *)VD_2[1].Value, 7), StringRef("callee4")); 544 ASSERT_EQ(4U, VD_2[1].Count); 545 ASSERT_EQ(StringRef((const char *)VD_2[2].Value, 7), StringRef("callee2")); 546 ASSERT_EQ(3U, VD_2[2].Count); 547 ASSERT_EQ(StringRef((const char *)VD_2[3].Value, 7), StringRef("callee1")); 548 ASSERT_EQ(1U, VD_2[3].Count); 549 550 std::unique_ptr<InstrProfValueData[]> VD_3( 551 R->getValueForSite(IPVK_IndirectCallTarget, 3)); 552 ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee1")); 553 ASSERT_EQ(1U, VD_3[0].Count); 554 555 std::unique_ptr<InstrProfValueData[]> VD_4( 556 R->getValueForSite(IPVK_IndirectCallTarget, 4)); 557 ASSERT_EQ(StringRef((const char *)VD_4[0].Value, 7), StringRef("callee3")); 558 ASSERT_EQ(6U, VD_4[0].Count); 559 ASSERT_EQ(StringRef((const char *)VD_4[1].Value, 7), StringRef("callee2")); 560 ASSERT_EQ(4U, VD_4[1].Count); 561 ASSERT_EQ(StringRef((const char *)VD_4[2].Value, 7), StringRef("callee1")); 562 ASSERT_EQ(2U, VD_4[2].Count); 563 } 564 565 TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge1_saturation) { 566 static const char bar[] = "bar"; 567 568 const uint64_t Max = std::numeric_limits<uint64_t>::max(); 569 570 instrprof_error Result; 571 auto Err = [&](Error E) { Result = InstrProfError::take(std::move(E)); }; 572 Result = instrprof_error::success; 573 Writer.addRecord({"foo", 0x1234, {1}}, Err); 574 ASSERT_EQ(Result, instrprof_error::success); 575 576 // Verify counter overflow. 577 Result = instrprof_error::success; 578 Writer.addRecord({"foo", 0x1234, {Max}}, Err); 579 ASSERT_EQ(Result, instrprof_error::counter_overflow); 580 581 Result = instrprof_error::success; 582 Writer.addRecord({bar, 0x9012, {8}}, Err); 583 ASSERT_EQ(Result, instrprof_error::success); 584 585 NamedInstrProfRecord Record4("baz", 0x5678, {3, 4}); 586 Record4.reserveSites(IPVK_IndirectCallTarget, 1); 587 InstrProfValueData VD4[] = {{uint64_t(bar), 1}}; 588 Record4.addValueData(IPVK_IndirectCallTarget, 0, VD4, 1, nullptr); 589 Result = instrprof_error::success; 590 Writer.addRecord(std::move(Record4), Err); 591 ASSERT_EQ(Result, instrprof_error::success); 592 593 // Verify value data counter overflow. 594 NamedInstrProfRecord Record5("baz", 0x5678, {5, 6}); 595 Record5.reserveSites(IPVK_IndirectCallTarget, 1); 596 InstrProfValueData VD5[] = {{uint64_t(bar), Max}}; 597 Record5.addValueData(IPVK_IndirectCallTarget, 0, VD5, 1, nullptr); 598 Result = instrprof_error::success; 599 Writer.addRecord(std::move(Record5), Err); 600 ASSERT_EQ(Result, instrprof_error::counter_overflow); 601 602 auto Profile = Writer.writeBuffer(); 603 readProfile(std::move(Profile)); 604 605 // Verify saturation of counts. 606 Expected<InstrProfRecord> ReadRecord1 = 607 Reader->getInstrProfRecord("foo", 0x1234); 608 EXPECT_THAT_ERROR(ReadRecord1.takeError(), Succeeded()); 609 ASSERT_EQ(Max, ReadRecord1->Counts[0]); 610 611 Expected<InstrProfRecord> ReadRecord2 = 612 Reader->getInstrProfRecord("baz", 0x5678); 613 ASSERT_TRUE(bool(ReadRecord2)); 614 ASSERT_EQ(1U, ReadRecord2->getNumValueSites(IPVK_IndirectCallTarget)); 615 std::unique_ptr<InstrProfValueData[]> VD = 616 ReadRecord2->getValueForSite(IPVK_IndirectCallTarget, 0); 617 ASSERT_EQ(StringRef("bar"), StringRef((const char *)VD[0].Value, 3)); 618 ASSERT_EQ(Max, VD[0].Count); 619 } 620 621 // This test tests that when there are too many values 622 // for a given site, the merged results are properly 623 // truncated. 624 TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge_site_trunc) { 625 static const char caller[] = "caller"; 626 627 NamedInstrProfRecord Record11(caller, 0x1234, {1, 2}); 628 NamedInstrProfRecord Record12(caller, 0x1234, {1, 2}); 629 630 // 2 value sites. 631 Record11.reserveSites(IPVK_IndirectCallTarget, 2); 632 InstrProfValueData VD0[255]; 633 for (int I = 0; I < 255; I++) { 634 VD0[I].Value = 2 * I; 635 VD0[I].Count = 2 * I + 1000; 636 } 637 638 Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 255, nullptr); 639 Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr); 640 641 Record12.reserveSites(IPVK_IndirectCallTarget, 2); 642 InstrProfValueData VD1[255]; 643 for (int I = 0; I < 255; I++) { 644 VD1[I].Value = 2 * I + 1; 645 VD1[I].Count = 2 * I + 1001; 646 } 647 648 Record12.addValueData(IPVK_IndirectCallTarget, 0, VD1, 255, nullptr); 649 Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr); 650 651 Writer.addRecord(std::move(Record11), Err); 652 // Merge profile data. 653 Writer.addRecord(std::move(Record12), Err); 654 655 auto Profile = Writer.writeBuffer(); 656 readProfile(std::move(Profile)); 657 658 Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234); 659 EXPECT_THAT_ERROR(R.takeError(), Succeeded()); 660 std::unique_ptr<InstrProfValueData[]> VD( 661 R->getValueForSite(IPVK_IndirectCallTarget, 0)); 662 ASSERT_EQ(2U, R->getNumValueSites(IPVK_IndirectCallTarget)); 663 ASSERT_EQ(255U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); 664 for (unsigned I = 0; I < 255; I++) { 665 ASSERT_EQ(VD[I].Value, 509 - I); 666 ASSERT_EQ(VD[I].Count, 1509 - I); 667 } 668 } 669 670 static void addValueProfData(InstrProfRecord &Record) { 671 Record.reserveSites(IPVK_IndirectCallTarget, 5); 672 InstrProfValueData VD0[] = {{uint64_t(callee1), 400}, 673 {uint64_t(callee2), 1000}, 674 {uint64_t(callee3), 500}, 675 {uint64_t(callee4), 300}, 676 {uint64_t(callee5), 100}}; 677 Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 5, nullptr); 678 InstrProfValueData VD1[] = {{uint64_t(callee5), 800}, 679 {uint64_t(callee3), 1000}, 680 {uint64_t(callee2), 2500}, 681 {uint64_t(callee1), 1300}}; 682 Record.addValueData(IPVK_IndirectCallTarget, 1, VD1, 4, nullptr); 683 InstrProfValueData VD2[] = {{uint64_t(callee6), 800}, 684 {uint64_t(callee3), 1000}, 685 {uint64_t(callee4), 5500}}; 686 Record.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr); 687 InstrProfValueData VD3[] = {{uint64_t(callee2), 1800}, 688 {uint64_t(callee3), 2000}}; 689 Record.addValueData(IPVK_IndirectCallTarget, 3, VD3, 2, nullptr); 690 Record.addValueData(IPVK_IndirectCallTarget, 4, nullptr, 0, nullptr); 691 } 692 693 TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write) { 694 InstrProfRecord SrcRecord({1ULL << 31, 2}); 695 addValueProfData(SrcRecord); 696 std::unique_ptr<ValueProfData> VPData = 697 ValueProfData::serializeFrom(SrcRecord); 698 699 InstrProfRecord Record({1ULL << 31, 2}); 700 VPData->deserializeTo(Record, nullptr); 701 702 // Now read data from Record and sanity check the data 703 ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget)); 704 ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); 705 ASSERT_EQ(4U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 1)); 706 ASSERT_EQ(3U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 2)); 707 ASSERT_EQ(2U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 3)); 708 ASSERT_EQ(0U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 4)); 709 710 auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) { 711 return VD1.Count > VD2.Count; 712 }; 713 std::unique_ptr<InstrProfValueData[]> VD_0( 714 Record.getValueForSite(IPVK_IndirectCallTarget, 0)); 715 llvm::sort(&VD_0[0], &VD_0[5], Cmp); 716 ASSERT_EQ(StringRef((const char *)VD_0[0].Value, 7), StringRef("callee2")); 717 ASSERT_EQ(1000U, VD_0[0].Count); 718 ASSERT_EQ(StringRef((const char *)VD_0[1].Value, 7), StringRef("callee3")); 719 ASSERT_EQ(500U, VD_0[1].Count); 720 ASSERT_EQ(StringRef((const char *)VD_0[2].Value, 7), StringRef("callee1")); 721 ASSERT_EQ(400U, VD_0[2].Count); 722 ASSERT_EQ(StringRef((const char *)VD_0[3].Value, 7), StringRef("callee4")); 723 ASSERT_EQ(300U, VD_0[3].Count); 724 ASSERT_EQ(StringRef((const char *)VD_0[4].Value, 7), StringRef("callee5")); 725 ASSERT_EQ(100U, VD_0[4].Count); 726 727 std::unique_ptr<InstrProfValueData[]> VD_1( 728 Record.getValueForSite(IPVK_IndirectCallTarget, 1)); 729 llvm::sort(&VD_1[0], &VD_1[4], Cmp); 730 ASSERT_EQ(StringRef((const char *)VD_1[0].Value, 7), StringRef("callee2")); 731 ASSERT_EQ(2500U, VD_1[0].Count); 732 ASSERT_EQ(StringRef((const char *)VD_1[1].Value, 7), StringRef("callee1")); 733 ASSERT_EQ(1300U, VD_1[1].Count); 734 ASSERT_EQ(StringRef((const char *)VD_1[2].Value, 7), StringRef("callee3")); 735 ASSERT_EQ(1000U, VD_1[2].Count); 736 ASSERT_EQ(StringRef((const char *)VD_1[3].Value, 7), StringRef("callee5")); 737 ASSERT_EQ(800U, VD_1[3].Count); 738 739 std::unique_ptr<InstrProfValueData[]> VD_2( 740 Record.getValueForSite(IPVK_IndirectCallTarget, 2)); 741 llvm::sort(&VD_2[0], &VD_2[3], Cmp); 742 ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee4")); 743 ASSERT_EQ(5500U, VD_2[0].Count); 744 ASSERT_EQ(StringRef((const char *)VD_2[1].Value, 7), StringRef("callee3")); 745 ASSERT_EQ(1000U, VD_2[1].Count); 746 ASSERT_EQ(StringRef((const char *)VD_2[2].Value, 7), StringRef("callee6")); 747 ASSERT_EQ(800U, VD_2[2].Count); 748 749 std::unique_ptr<InstrProfValueData[]> VD_3( 750 Record.getValueForSite(IPVK_IndirectCallTarget, 3)); 751 llvm::sort(&VD_3[0], &VD_3[2], Cmp); 752 ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee3")); 753 ASSERT_EQ(2000U, VD_3[0].Count); 754 ASSERT_EQ(StringRef((const char *)VD_3[1].Value, 7), StringRef("callee2")); 755 ASSERT_EQ(1800U, VD_3[1].Count); 756 } 757 758 TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write_mapping) { 759 760 NamedInstrProfRecord SrcRecord("caller", 0x1234, {1ULL << 31, 2}); 761 addValueProfData(SrcRecord); 762 std::unique_ptr<ValueProfData> VPData = 763 ValueProfData::serializeFrom(SrcRecord); 764 765 NamedInstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2}); 766 InstrProfSymtab Symtab; 767 Symtab.mapAddress(uint64_t(callee1), 0x1000ULL); 768 Symtab.mapAddress(uint64_t(callee2), 0x2000ULL); 769 Symtab.mapAddress(uint64_t(callee3), 0x3000ULL); 770 Symtab.mapAddress(uint64_t(callee4), 0x4000ULL); 771 // Missing mapping for callee5 772 773 VPData->deserializeTo(Record, &Symtab); 774 775 // Now read data from Record and sanity check the data 776 ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget)); 777 ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); 778 779 auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) { 780 return VD1.Count > VD2.Count; 781 }; 782 std::unique_ptr<InstrProfValueData[]> VD_0( 783 Record.getValueForSite(IPVK_IndirectCallTarget, 0)); 784 llvm::sort(&VD_0[0], &VD_0[5], Cmp); 785 ASSERT_EQ(VD_0[0].Value, 0x2000ULL); 786 ASSERT_EQ(1000U, VD_0[0].Count); 787 ASSERT_EQ(VD_0[1].Value, 0x3000ULL); 788 ASSERT_EQ(500U, VD_0[1].Count); 789 ASSERT_EQ(VD_0[2].Value, 0x1000ULL); 790 ASSERT_EQ(400U, VD_0[2].Count); 791 792 // callee5 does not have a mapped value -- default to 0. 793 ASSERT_EQ(VD_0[4].Value, 0ULL); 794 } 795 796 TEST_P(MaybeSparseInstrProfTest, get_max_function_count) { 797 Writer.addRecord({"foo", 0x1234, {1ULL << 31, 2}}, Err); 798 Writer.addRecord({"bar", 0, {1ULL << 63}}, Err); 799 Writer.addRecord({"baz", 0x5678, {0, 0, 0, 0}}, Err); 800 auto Profile = Writer.writeBuffer(); 801 readProfile(std::move(Profile)); 802 803 ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount()); 804 } 805 806 TEST_P(MaybeSparseInstrProfTest, get_weighted_function_counts) { 807 Writer.addRecord({"foo", 0x1234, {1, 2}}, 3, Err); 808 Writer.addRecord({"foo", 0x1235, {3, 4}}, 5, Err); 809 auto Profile = Writer.writeBuffer(); 810 readProfile(std::move(Profile)); 811 812 std::vector<uint64_t> Counts; 813 EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1234, Counts), 814 Succeeded()); 815 ASSERT_EQ(2U, Counts.size()); 816 ASSERT_EQ(3U, Counts[0]); 817 ASSERT_EQ(6U, Counts[1]); 818 819 EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1235, Counts), 820 Succeeded()); 821 ASSERT_EQ(2U, Counts.size()); 822 ASSERT_EQ(15U, Counts[0]); 823 ASSERT_EQ(20U, Counts[1]); 824 } 825 826 // Testing symtab creator interface used by indexed profile reader. 827 TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_test) { 828 std::vector<StringRef> FuncNames; 829 FuncNames.push_back("func1"); 830 FuncNames.push_back("func2"); 831 FuncNames.push_back("func3"); 832 FuncNames.push_back("bar1"); 833 FuncNames.push_back("bar2"); 834 FuncNames.push_back("bar3"); 835 InstrProfSymtab Symtab; 836 EXPECT_THAT_ERROR(Symtab.create(FuncNames), Succeeded()); 837 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1")); 838 ASSERT_EQ(StringRef("func1"), R); 839 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2")); 840 ASSERT_EQ(StringRef("func2"), R); 841 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3")); 842 ASSERT_EQ(StringRef("func3"), R); 843 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1")); 844 ASSERT_EQ(StringRef("bar1"), R); 845 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2")); 846 ASSERT_EQ(StringRef("bar2"), R); 847 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3")); 848 ASSERT_EQ(StringRef("bar3"), R); 849 850 // negative tests 851 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar4")); 852 ASSERT_EQ(StringRef(), R); 853 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("foo4")); 854 ASSERT_EQ(StringRef(), R); 855 856 // Now incrementally update the symtab 857 EXPECT_THAT_ERROR(Symtab.addFuncName("blah_1"), Succeeded()); 858 EXPECT_THAT_ERROR(Symtab.addFuncName("blah_2"), Succeeded()); 859 EXPECT_THAT_ERROR(Symtab.addFuncName("blah_3"), Succeeded()); 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 Writer.addRecord({"foo", 0x1234, {0}}, Err); 995 Writer.addRecord({"bar", 0x4321, {0, 0}}, Err); 996 Writer.addRecord({"baz", 0x4321, {0, 0, 0}}, Err); 997 998 auto Profile = Writer.writeBuffer(); 999 readProfile(std::move(Profile)); 1000 1001 auto I = Reader->begin(), E = Reader->end(); 1002 ASSERT_TRUE(I == E); 1003 } 1004 1005 INSTANTIATE_TEST_CASE_P(MaybeSparse, MaybeSparseInstrProfTest, 1006 ::testing::Bool(),); 1007 1008 } // end anonymous namespace 1009