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 std::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 std::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 std::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 std::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 Symtab.finalizeSymtab(); 773 774 VPData->deserializeTo(Record, &Symtab.getAddrHashMap()); 775 776 // Now read data from Record and sanity check the data 777 ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget)); 778 ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); 779 780 auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) { 781 return VD1.Count > VD2.Count; 782 }; 783 std::unique_ptr<InstrProfValueData[]> VD_0( 784 Record.getValueForSite(IPVK_IndirectCallTarget, 0)); 785 std::sort(&VD_0[0], &VD_0[5], Cmp); 786 ASSERT_EQ(VD_0[0].Value, 0x2000ULL); 787 ASSERT_EQ(1000U, VD_0[0].Count); 788 ASSERT_EQ(VD_0[1].Value, 0x3000ULL); 789 ASSERT_EQ(500U, VD_0[1].Count); 790 ASSERT_EQ(VD_0[2].Value, 0x1000ULL); 791 ASSERT_EQ(400U, VD_0[2].Count); 792 793 // callee5 does not have a mapped value -- default to 0. 794 ASSERT_EQ(VD_0[4].Value, 0ULL); 795 } 796 797 TEST_P(MaybeSparseInstrProfTest, get_max_function_count) { 798 Writer.addRecord({"foo", 0x1234, {1ULL << 31, 2}}, Err); 799 Writer.addRecord({"bar", 0, {1ULL << 63}}, Err); 800 Writer.addRecord({"baz", 0x5678, {0, 0, 0, 0}}, Err); 801 auto Profile = Writer.writeBuffer(); 802 readProfile(std::move(Profile)); 803 804 ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount()); 805 } 806 807 TEST_P(MaybeSparseInstrProfTest, get_weighted_function_counts) { 808 Writer.addRecord({"foo", 0x1234, {1, 2}}, 3, Err); 809 Writer.addRecord({"foo", 0x1235, {3, 4}}, 5, Err); 810 auto Profile = Writer.writeBuffer(); 811 readProfile(std::move(Profile)); 812 813 std::vector<uint64_t> Counts; 814 EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1234, Counts), 815 Succeeded()); 816 ASSERT_EQ(2U, Counts.size()); 817 ASSERT_EQ(3U, Counts[0]); 818 ASSERT_EQ(6U, Counts[1]); 819 820 EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1235, Counts), 821 Succeeded()); 822 ASSERT_EQ(2U, Counts.size()); 823 ASSERT_EQ(15U, Counts[0]); 824 ASSERT_EQ(20U, Counts[1]); 825 } 826 827 // Testing symtab creator interface used by indexed profile reader. 828 TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_test) { 829 std::vector<StringRef> FuncNames; 830 FuncNames.push_back("func1"); 831 FuncNames.push_back("func2"); 832 FuncNames.push_back("func3"); 833 FuncNames.push_back("bar1"); 834 FuncNames.push_back("bar2"); 835 FuncNames.push_back("bar3"); 836 InstrProfSymtab Symtab; 837 EXPECT_THAT_ERROR(Symtab.create(FuncNames), Succeeded()); 838 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1")); 839 ASSERT_EQ(StringRef("func1"), R); 840 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2")); 841 ASSERT_EQ(StringRef("func2"), R); 842 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3")); 843 ASSERT_EQ(StringRef("func3"), R); 844 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1")); 845 ASSERT_EQ(StringRef("bar1"), R); 846 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2")); 847 ASSERT_EQ(StringRef("bar2"), R); 848 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3")); 849 ASSERT_EQ(StringRef("bar3"), R); 850 851 // negative tests 852 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar4")); 853 ASSERT_EQ(StringRef(), R); 854 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("foo4")); 855 ASSERT_EQ(StringRef(), R); 856 857 // Now incrementally update the symtab 858 EXPECT_THAT_ERROR(Symtab.addFuncName("blah_1"), Succeeded()); 859 EXPECT_THAT_ERROR(Symtab.addFuncName("blah_2"), Succeeded()); 860 EXPECT_THAT_ERROR(Symtab.addFuncName("blah_3"), Succeeded()); 861 // Finalize it 862 Symtab.finalizeSymtab(); 863 864 // Check again 865 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_1")); 866 ASSERT_EQ(StringRef("blah_1"), R); 867 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_2")); 868 ASSERT_EQ(StringRef("blah_2"), R); 869 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_3")); 870 ASSERT_EQ(StringRef("blah_3"), R); 871 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1")); 872 ASSERT_EQ(StringRef("func1"), R); 873 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2")); 874 ASSERT_EQ(StringRef("func2"), R); 875 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3")); 876 ASSERT_EQ(StringRef("func3"), R); 877 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1")); 878 ASSERT_EQ(StringRef("bar1"), R); 879 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2")); 880 ASSERT_EQ(StringRef("bar2"), R); 881 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3")); 882 ASSERT_EQ(StringRef("bar3"), R); 883 } 884 885 // Test that we get an error when creating a bogus symtab. 886 TEST_P(MaybeSparseInstrProfTest, instr_prof_bogus_symtab_empty_func_name) { 887 InstrProfSymtab Symtab; 888 EXPECT_TRUE(ErrorEquals(instrprof_error::malformed, Symtab.addFuncName(""))); 889 } 890 891 // Testing symtab creator interface used by value profile transformer. 892 TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_module_test) { 893 LLVMContext Ctx; 894 std::unique_ptr<Module> M = llvm::make_unique<Module>("MyModule.cpp", Ctx); 895 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx), 896 /*isVarArg=*/false); 897 Function::Create(FTy, Function::ExternalLinkage, "Gfoo", M.get()); 898 Function::Create(FTy, Function::ExternalLinkage, "Gblah", M.get()); 899 Function::Create(FTy, Function::ExternalLinkage, "Gbar", M.get()); 900 Function::Create(FTy, Function::InternalLinkage, "Ifoo", M.get()); 901 Function::Create(FTy, Function::InternalLinkage, "Iblah", M.get()); 902 Function::Create(FTy, Function::InternalLinkage, "Ibar", M.get()); 903 Function::Create(FTy, Function::PrivateLinkage, "Pfoo", M.get()); 904 Function::Create(FTy, Function::PrivateLinkage, "Pblah", M.get()); 905 Function::Create(FTy, Function::PrivateLinkage, "Pbar", M.get()); 906 Function::Create(FTy, Function::WeakODRLinkage, "Wfoo", M.get()); 907 Function::Create(FTy, Function::WeakODRLinkage, "Wblah", M.get()); 908 Function::Create(FTy, Function::WeakODRLinkage, "Wbar", M.get()); 909 910 InstrProfSymtab ProfSymtab; 911 EXPECT_THAT_ERROR(ProfSymtab.create(*M), Succeeded()); 912 913 StringRef Funcs[] = {"Gfoo", "Gblah", "Gbar", "Ifoo", "Iblah", "Ibar", 914 "Pfoo", "Pblah", "Pbar", "Wfoo", "Wblah", "Wbar"}; 915 916 for (unsigned I = 0; I < sizeof(Funcs) / sizeof(*Funcs); I++) { 917 Function *F = M->getFunction(Funcs[I]); 918 ASSERT_TRUE(F != nullptr); 919 std::string PGOName = getPGOFuncName(*F); 920 uint64_t Key = IndexedInstrProf::ComputeHash(PGOName); 921 ASSERT_EQ(StringRef(PGOName), 922 ProfSymtab.getFuncName(Key)); 923 ASSERT_EQ(StringRef(Funcs[I]), ProfSymtab.getOrigFuncName(Key)); 924 } 925 } 926 927 // Testing symtab serialization and creator/deserialization interface 928 // used by coverage map reader, and raw profile reader. 929 TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_compression_test) { 930 std::vector<std::string> FuncNames1; 931 std::vector<std::string> FuncNames2; 932 for (int I = 0; I < 3; I++) { 933 std::string str; 934 raw_string_ostream OS(str); 935 OS << "func_" << I; 936 FuncNames1.push_back(OS.str()); 937 str.clear(); 938 OS << "f oooooooooooooo_" << I; 939 FuncNames1.push_back(OS.str()); 940 str.clear(); 941 OS << "BAR_" << I; 942 FuncNames2.push_back(OS.str()); 943 str.clear(); 944 OS << "BlahblahBlahblahBar_" << I; 945 FuncNames2.push_back(OS.str()); 946 } 947 948 for (bool DoCompression : {false, true}) { 949 // Compressing: 950 std::string FuncNameStrings1; 951 EXPECT_THAT_ERROR(collectPGOFuncNameStrings( 952 FuncNames1, (DoCompression && zlib::isAvailable()), 953 FuncNameStrings1), 954 Succeeded()); 955 956 // Compressing: 957 std::string FuncNameStrings2; 958 EXPECT_THAT_ERROR(collectPGOFuncNameStrings( 959 FuncNames2, (DoCompression && zlib::isAvailable()), 960 FuncNameStrings2), 961 Succeeded()); 962 963 for (int Padding = 0; Padding < 2; Padding++) { 964 // Join with paddings : 965 std::string FuncNameStrings = FuncNameStrings1; 966 for (int P = 0; P < Padding; P++) { 967 FuncNameStrings.push_back('\0'); 968 } 969 FuncNameStrings += FuncNameStrings2; 970 971 // Now decompress: 972 InstrProfSymtab Symtab; 973 EXPECT_THAT_ERROR(Symtab.create(StringRef(FuncNameStrings)), Succeeded()); 974 975 // Now do the checks: 976 // First sampling some data points: 977 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[0])); 978 ASSERT_EQ(StringRef("func_0"), R); 979 R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[1])); 980 ASSERT_EQ(StringRef("f oooooooooooooo_0"), R); 981 for (int I = 0; I < 3; I++) { 982 std::string N[4]; 983 N[0] = FuncNames1[2 * I]; 984 N[1] = FuncNames1[2 * I + 1]; 985 N[2] = FuncNames2[2 * I]; 986 N[3] = FuncNames2[2 * I + 1]; 987 for (int J = 0; J < 4; J++) { 988 StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(N[J])); 989 ASSERT_EQ(StringRef(N[J]), R); 990 } 991 } 992 } 993 } 994 } 995 996 TEST_F(SparseInstrProfTest, preserve_no_records) { 997 Writer.addRecord({"foo", 0x1234, {0}}, Err); 998 Writer.addRecord({"bar", 0x4321, {0, 0}}, Err); 999 Writer.addRecord({"baz", 0x4321, {0, 0, 0}}, Err); 1000 1001 auto Profile = Writer.writeBuffer(); 1002 readProfile(std::move(Profile)); 1003 1004 auto I = Reader->begin(), E = Reader->end(); 1005 ASSERT_TRUE(I == E); 1006 } 1007 1008 INSTANTIATE_TEST_CASE_P(MaybeSparse, MaybeSparseInstrProfTest, 1009 ::testing::Bool(),); 1010 1011 } // end anonymous namespace 1012