InstrProfTest.cpp 42 KB

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