1ffec81caSEugene Zelenko //===- unittest/ProfileData/InstrProfTest.cpp -------------------*- C++ -*-===//
22b6c537bSJustin Bogner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62b6c537bSJustin Bogner //
72b6c537bSJustin Bogner //===----------------------------------------------------------------------===//
82b6c537bSJustin Bogner
959411db5SXinliang David Li #include "llvm/IR/Function.h"
10402477d2SXinliang David Li #include "llvm/IR/IRBuilder.h"
1159411db5SXinliang David Li #include "llvm/IR/LLVMContext.h"
1259411db5SXinliang David Li #include "llvm/IR/Module.h"
132b6c537bSJustin Bogner #include "llvm/ProfileData/InstrProfReader.h"
142b6c537bSJustin Bogner #include "llvm/ProfileData/InstrProfWriter.h"
150a418490SSnehasish Kumar #include "llvm/ProfileData/MemProf.h"
1627a4f254SSnehasish Kumar #include "llvm/ProfileData/MemProfData.inc"
17e413f1a0SXinliang David Li #include "llvm/Support/Compression.h"
186dd6a616SSnehasish Kumar #include "llvm/Support/raw_ostream.h"
1994b98b2cSDavid Blaikie #include "llvm/Testing/Support/Error.h"
2094b98b2cSDavid Blaikie #include "llvm/Testing/Support/SupportHelpers.h"
212b6c537bSJustin Bogner #include "gtest/gtest.h"
222b6c537bSJustin Bogner #include <cstdarg>
232b6c537bSJustin Bogner
242b6c537bSJustin Bogner using namespace llvm;
252b6c537bSJustin Bogner
2694b98b2cSDavid Blaikie LLVM_NODISCARD static ::testing::AssertionResult
ErrorEquals(instrprof_error Expected,Error E)2794b98b2cSDavid Blaikie ErrorEquals(instrprof_error Expected, Error E) {
289152fd17SVedant Kumar instrprof_error Found;
299152fd17SVedant Kumar std::string FoundMsg;
309152fd17SVedant Kumar handleAllErrors(std::move(E), [&](const InstrProfError &IPE) {
319152fd17SVedant Kumar Found = IPE.get();
329152fd17SVedant Kumar FoundMsg = IPE.message();
339152fd17SVedant Kumar });
342b6c537bSJustin Bogner if (Expected == Found)
352b6c537bSJustin Bogner return ::testing::AssertionSuccess();
369152fd17SVedant Kumar return ::testing::AssertionFailure() << "error: " << FoundMsg << "\n";
372b6c537bSJustin Bogner }
382b6c537bSJustin Bogner
392b6c537bSJustin Bogner namespace {
402b6c537bSJustin Bogner
412b6c537bSJustin Bogner struct InstrProfTest : ::testing::Test {
422b6c537bSJustin Bogner InstrProfWriter Writer;
432b6c537bSJustin Bogner std::unique_ptr<IndexedInstrProfReader> Reader;
442b6c537bSJustin Bogner
SetUp__anon741d935d0211::InstrProfTest4531eb8349SLogan Smith void SetUp() override { Writer.setOutputSparse(false); }
4600dab228SVedant Kumar
readProfile__anon741d935d0211::InstrProfTest47ceed4eb1SRichard Smith void readProfile(std::unique_ptr<MemoryBuffer> Profile,
48ceed4eb1SRichard Smith std::unique_ptr<MemoryBuffer> Remapping = nullptr) {
49ceed4eb1SRichard Smith auto ReaderOrErr = IndexedInstrProfReader::create(std::move(Profile),
50ceed4eb1SRichard Smith std::move(Remapping));
5194b98b2cSDavid Blaikie EXPECT_THAT_ERROR(ReaderOrErr.takeError(), Succeeded());
522b6c537bSJustin Bogner Reader = std::move(ReaderOrErr.get());
532b6c537bSJustin Bogner }
542b6c537bSJustin Bogner };
552b6c537bSJustin Bogner
5600dab228SVedant Kumar struct SparseInstrProfTest : public InstrProfTest {
SetUp__anon741d935d0211::SparseInstrProfTest5731eb8349SLogan Smith void SetUp() override { Writer.setOutputSparse(true); }
5800dab228SVedant Kumar };
5900dab228SVedant Kumar
6000dab228SVedant Kumar struct MaybeSparseInstrProfTest : public InstrProfTest,
6100dab228SVedant Kumar public ::testing::WithParamInterface<bool> {
SetUp__anon741d935d0211::MaybeSparseInstrProfTest6231eb8349SLogan Smith void SetUp() override { Writer.setOutputSparse(GetParam()); }
6300dab228SVedant Kumar };
6400dab228SVedant Kumar
TEST_P(MaybeSparseInstrProfTest,write_and_read_empty_profile)6500dab228SVedant Kumar TEST_P(MaybeSparseInstrProfTest, write_and_read_empty_profile) {
662b6c537bSJustin Bogner auto Profile = Writer.writeBuffer();
672b6c537bSJustin Bogner readProfile(std::move(Profile));
682b6c537bSJustin Bogner ASSERT_TRUE(Reader->begin() == Reader->end());
692b6c537bSJustin Bogner }
702b6c537bSJustin Bogner
__anon741d935d0302(Error E) 7198cce003SDavid Blaikie static const auto Err = [](Error E) {
7298cce003SDavid Blaikie consumeError(std::move(E));
7398cce003SDavid Blaikie FAIL();
7498cce003SDavid Blaikie };
7598cce003SDavid Blaikie
TEST_P(MaybeSparseInstrProfTest,write_and_read_one_function)7600dab228SVedant Kumar TEST_P(MaybeSparseInstrProfTest, write_and_read_one_function) {
7798cce003SDavid Blaikie Writer.addRecord({"foo", 0x1234, {1, 2, 3, 4}}, Err);
782b6c537bSJustin Bogner auto Profile = Writer.writeBuffer();
792b6c537bSJustin Bogner readProfile(std::move(Profile));
802b6c537bSJustin Bogner
812b6c537bSJustin Bogner auto I = Reader->begin(), E = Reader->end();
822b6c537bSJustin Bogner ASSERT_TRUE(I != E);
832b6c537bSJustin Bogner ASSERT_EQ(StringRef("foo"), I->Name);
842b6c537bSJustin Bogner ASSERT_EQ(0x1234U, I->Hash);
852b6c537bSJustin Bogner ASSERT_EQ(4U, I->Counts.size());
862b6c537bSJustin Bogner ASSERT_EQ(1U, I->Counts[0]);
872b6c537bSJustin Bogner ASSERT_EQ(2U, I->Counts[1]);
882b6c537bSJustin Bogner ASSERT_EQ(3U, I->Counts[2]);
892b6c537bSJustin Bogner ASSERT_EQ(4U, I->Counts[3]);
902b6c537bSJustin Bogner ASSERT_TRUE(++I == E);
912b6c537bSJustin Bogner }
922b6c537bSJustin Bogner
TEST_P(MaybeSparseInstrProfTest,get_instr_prof_record)9300dab228SVedant Kumar TEST_P(MaybeSparseInstrProfTest, get_instr_prof_record) {
9498cce003SDavid Blaikie Writer.addRecord({"foo", 0x1234, {1, 2}}, Err);
9598cce003SDavid Blaikie Writer.addRecord({"foo", 0x1235, {3, 4}}, Err);
962004f003SXinliang David Li auto Profile = Writer.writeBuffer();
972004f003SXinliang David Li readProfile(std::move(Profile));
982004f003SXinliang David Li
999152fd17SVedant Kumar Expected<InstrProfRecord> R = Reader->getInstrProfRecord("foo", 0x1234);
10094b98b2cSDavid Blaikie EXPECT_THAT_ERROR(R.takeError(), Succeeded());
101fed557efSDavid Blaikie ASSERT_EQ(2U, R->Counts.size());
102fed557efSDavid Blaikie ASSERT_EQ(1U, R->Counts[0]);
103fed557efSDavid Blaikie ASSERT_EQ(2U, R->Counts[1]);
1042004f003SXinliang David Li
1052004f003SXinliang David Li R = Reader->getInstrProfRecord("foo", 0x1235);
10694b98b2cSDavid Blaikie EXPECT_THAT_ERROR(R.takeError(), Succeeded());
107fed557efSDavid Blaikie ASSERT_EQ(2U, R->Counts.size());
108fed557efSDavid Blaikie ASSERT_EQ(3U, R->Counts[0]);
109fed557efSDavid Blaikie ASSERT_EQ(4U, R->Counts[1]);
1102004f003SXinliang David Li
1112004f003SXinliang David Li R = Reader->getInstrProfRecord("foo", 0x5678);
1129152fd17SVedant Kumar ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, R.takeError()));
1132004f003SXinliang David Li
1142004f003SXinliang David Li R = Reader->getInstrProfRecord("bar", 0x1234);
1159152fd17SVedant Kumar ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, R.takeError()));
1162004f003SXinliang David Li }
1172004f003SXinliang David Li
TEST_P(MaybeSparseInstrProfTest,get_function_counts)11800dab228SVedant Kumar TEST_P(MaybeSparseInstrProfTest, get_function_counts) {
11998cce003SDavid Blaikie Writer.addRecord({"foo", 0x1234, {1, 2}}, Err);
12098cce003SDavid Blaikie Writer.addRecord({"foo", 0x1235, {3, 4}}, Err);
1212b6c537bSJustin Bogner auto Profile = Writer.writeBuffer();
1222b6c537bSJustin Bogner readProfile(std::move(Profile));
1232b6c537bSJustin Bogner
1242b6c537bSJustin Bogner std::vector<uint64_t> Counts;
12594b98b2cSDavid Blaikie EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1234, Counts),
12694b98b2cSDavid Blaikie Succeeded());
1272b6c537bSJustin Bogner ASSERT_EQ(2U, Counts.size());
1282b6c537bSJustin Bogner ASSERT_EQ(1U, Counts[0]);
1292b6c537bSJustin Bogner ASSERT_EQ(2U, Counts[1]);
1302b6c537bSJustin Bogner
13194b98b2cSDavid Blaikie EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1235, Counts),
13294b98b2cSDavid Blaikie Succeeded());
13309829f44SJustin Bogner ASSERT_EQ(2U, Counts.size());
13409829f44SJustin Bogner ASSERT_EQ(3U, Counts[0]);
13509829f44SJustin Bogner ASSERT_EQ(4U, Counts[1]);
13609829f44SJustin Bogner
1379152fd17SVedant Kumar Error E1 = Reader->getFunctionCounts("foo", 0x5678, Counts);
1389152fd17SVedant Kumar ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, std::move(E1)));
1392b6c537bSJustin Bogner
1409152fd17SVedant Kumar Error E2 = Reader->getFunctionCounts("bar", 0x1234, Counts);
1419152fd17SVedant Kumar ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, std::move(E2)));
1422b6c537bSJustin Bogner }
1432b6c537bSJustin Bogner
1446c93ee8dSXinliang David Li // Profile data is copied from general.proftext
TEST_F(InstrProfTest,get_profile_summary)1456c93ee8dSXinliang David Li TEST_F(InstrProfTest, get_profile_summary) {
14698cce003SDavid Blaikie Writer.addRecord({"func1", 0x1234, {97531}}, Err);
14798cce003SDavid Blaikie Writer.addRecord({"func2", 0x1234, {0, 0}}, Err);
14898cce003SDavid Blaikie Writer.addRecord(
14998cce003SDavid Blaikie {"func3",
1505b079d83SDavid Blaikie 0x1234,
15198cce003SDavid Blaikie {2305843009213693952, 1152921504606846976, 576460752303423488,
15298cce003SDavid Blaikie 288230376151711744, 144115188075855872, 72057594037927936}},
15398cce003SDavid Blaikie Err);
15498cce003SDavid Blaikie Writer.addRecord({"func4", 0x1234, {0}}, Err);
1556c93ee8dSXinliang David Li auto Profile = Writer.writeBuffer();
1566c93ee8dSXinliang David Li readProfile(std::move(Profile));
1576c93ee8dSXinliang David Li
1587cefdb81SEaswaran Raman auto VerifySummary = [](ProfileSummary &IPS) mutable {
1597cefdb81SEaswaran Raman ASSERT_EQ(ProfileSummary::PSK_Instr, IPS.getKind());
1607c4f25d2SEaswaran Raman ASSERT_EQ(2305843009213693952U, IPS.getMaxFunctionCount());
1617cefdb81SEaswaran Raman ASSERT_EQ(2305843009213693952U, IPS.getMaxCount());
1627cefdb81SEaswaran Raman ASSERT_EQ(10U, IPS.getNumCounts());
1637c4f25d2SEaswaran Raman ASSERT_EQ(4539628424389557499U, IPS.getTotalCount());
164d6790a0aSMircea Trofin const std::vector<ProfileSummaryEntry> &Details = IPS.getDetailedSummary();
1656c93ee8dSXinliang David Li uint32_t Cutoff = 800000;
1666c93ee8dSXinliang David Li auto Predicate = [&Cutoff](const ProfileSummaryEntry &PE) {
1676c93ee8dSXinliang David Li return PE.Cutoff == Cutoff;
1686c93ee8dSXinliang David Li };
169562e8294SDavid Majnemer auto EightyPerc = find_if(Details, Predicate);
1706c93ee8dSXinliang David Li Cutoff = 900000;
171562e8294SDavid Majnemer auto NinetyPerc = find_if(Details, Predicate);
1726c93ee8dSXinliang David Li Cutoff = 950000;
173562e8294SDavid Majnemer auto NinetyFivePerc = find_if(Details, Predicate);
1746c93ee8dSXinliang David Li Cutoff = 990000;
175562e8294SDavid Majnemer auto NinetyNinePerc = find_if(Details, Predicate);
1764309570dSEaswaran Raman ASSERT_EQ(576460752303423488U, EightyPerc->MinCount);
1774309570dSEaswaran Raman ASSERT_EQ(288230376151711744U, NinetyPerc->MinCount);
1784309570dSEaswaran Raman ASSERT_EQ(288230376151711744U, NinetyFivePerc->MinCount);
1794309570dSEaswaran Raman ASSERT_EQ(72057594037927936U, NinetyNinePerc->MinCount);
1807c4f25d2SEaswaran Raman };
181a6ff69f6SRong Xu ProfileSummary &PS = Reader->getSummary(/* IsCS */ false);
182f9709ee0SEaswaran Raman VerifySummary(PS);
18326628d30SEaswaran Raman
18426628d30SEaswaran Raman // Test that conversion of summary to and from Metadata works.
18503b42e41SMehdi Amini LLVMContext Context;
18603b42e41SMehdi Amini Metadata *MD = PS.getMD(Context);
1877c4f25d2SEaswaran Raman ASSERT_TRUE(MD);
1887c4f25d2SEaswaran Raman ProfileSummary *PSFromMD = ProfileSummary::getFromMD(MD);
1897c4f25d2SEaswaran Raman ASSERT_TRUE(PSFromMD);
1907cefdb81SEaswaran Raman VerifySummary(*PSFromMD);
1917cefdb81SEaswaran Raman delete PSFromMD;
19226628d30SEaswaran Raman
19326628d30SEaswaran Raman // Test that summary can be attached to and read back from module.
19403b42e41SMehdi Amini Module M("my_module", Context);
195a6ff69f6SRong Xu M.setProfileSummary(MD, ProfileSummary::PSK_Instr);
196a6ff69f6SRong Xu MD = M.getProfileSummary(/* IsCS */ false);
19726628d30SEaswaran Raman ASSERT_TRUE(MD);
19826628d30SEaswaran Raman PSFromMD = ProfileSummary::getFromMD(MD);
19926628d30SEaswaran Raman ASSERT_TRUE(PSFromMD);
2007cefdb81SEaswaran Raman VerifySummary(*PSFromMD);
2017cefdb81SEaswaran Raman delete PSFromMD;
2026c93ee8dSXinliang David Li }
2036c93ee8dSXinliang David Li
TEST_F(InstrProfTest,test_writer_merge)204e3a0bf50SVedant Kumar TEST_F(InstrProfTest, test_writer_merge) {
20598cce003SDavid Blaikie Writer.addRecord({"func1", 0x1234, {42}}, Err);
206e3a0bf50SVedant Kumar
207e3a0bf50SVedant Kumar InstrProfWriter Writer2;
20898cce003SDavid Blaikie Writer2.addRecord({"func2", 0x1234, {0, 0}}, Err);
209e3a0bf50SVedant Kumar
21098cce003SDavid Blaikie Writer.mergeRecordsFromWriter(std::move(Writer2), Err);
211e3a0bf50SVedant Kumar
212e3a0bf50SVedant Kumar auto Profile = Writer.writeBuffer();
213e3a0bf50SVedant Kumar readProfile(std::move(Profile));
214e3a0bf50SVedant Kumar
215e3a0bf50SVedant Kumar Expected<InstrProfRecord> R = Reader->getInstrProfRecord("func1", 0x1234);
21694b98b2cSDavid Blaikie EXPECT_THAT_ERROR(R.takeError(), Succeeded());
217e3a0bf50SVedant Kumar ASSERT_EQ(1U, R->Counts.size());
218e3a0bf50SVedant Kumar ASSERT_EQ(42U, R->Counts[0]);
219e3a0bf50SVedant Kumar
220e3a0bf50SVedant Kumar R = Reader->getInstrProfRecord("func2", 0x1234);
22194b98b2cSDavid Blaikie EXPECT_THAT_ERROR(R.takeError(), Succeeded());
222e3a0bf50SVedant Kumar ASSERT_EQ(2U, R->Counts.size());
223e3a0bf50SVedant Kumar ASSERT_EQ(0U, R->Counts[0]);
224e3a0bf50SVedant Kumar ASSERT_EQ(0U, R->Counts[1]);
225e3a0bf50SVedant Kumar }
226e3a0bf50SVedant Kumar
2276dd6a616SSnehasish Kumar using ::llvm::memprof::IndexedMemProfRecord;
22827a4f254SSnehasish Kumar using ::llvm::memprof::MemInfoBlock;
2296dd6a616SSnehasish Kumar using FrameIdMapTy =
2306dd6a616SSnehasish Kumar llvm::DenseMap<::llvm::memprof::FrameId, ::llvm::memprof::Frame>;
2316dd6a616SSnehasish Kumar
getFrameMapping()2326dd6a616SSnehasish Kumar static FrameIdMapTy getFrameMapping() {
2336dd6a616SSnehasish Kumar FrameIdMapTy Mapping;
2346dd6a616SSnehasish Kumar Mapping.insert({0, {0x123, 1, 2, false}});
2356dd6a616SSnehasish Kumar Mapping.insert({1, {0x345, 3, 4, true}});
2366dd6a616SSnehasish Kumar Mapping.insert({2, {0x125, 5, 6, false}});
2376dd6a616SSnehasish Kumar Mapping.insert({3, {0x567, 7, 8, true}});
2386dd6a616SSnehasish Kumar Mapping.insert({4, {0x124, 5, 6, false}});
2396dd6a616SSnehasish Kumar Mapping.insert({5, {0x789, 8, 9, true}});
2406dd6a616SSnehasish Kumar return Mapping;
2416dd6a616SSnehasish Kumar }
2426dd6a616SSnehasish Kumar
makeRecord(std::initializer_list<std::initializer_list<::llvm::memprof::FrameId>> AllocFrames,std::initializer_list<std::initializer_list<::llvm::memprof::FrameId>> CallSiteFrames,const MemInfoBlock & Block=MemInfoBlock ())2436dd6a616SSnehasish Kumar IndexedMemProfRecord makeRecord(
2446dd6a616SSnehasish Kumar std::initializer_list<std::initializer_list<::llvm::memprof::FrameId>>
24527a4f254SSnehasish Kumar AllocFrames,
2466dd6a616SSnehasish Kumar std::initializer_list<std::initializer_list<::llvm::memprof::FrameId>>
24727a4f254SSnehasish Kumar CallSiteFrames,
24827a4f254SSnehasish Kumar const MemInfoBlock &Block = MemInfoBlock()) {
2496dd6a616SSnehasish Kumar llvm::memprof::IndexedMemProfRecord MR;
25027a4f254SSnehasish Kumar for (const auto &Frames : AllocFrames)
25127a4f254SSnehasish Kumar MR.AllocSites.emplace_back(Frames, Block);
25227a4f254SSnehasish Kumar for (const auto &Frames : CallSiteFrames)
25327a4f254SSnehasish Kumar MR.CallSites.push_back(Frames);
25427a4f254SSnehasish Kumar return MR;
25527a4f254SSnehasish Kumar }
25627a4f254SSnehasish Kumar
2576dd6a616SSnehasish Kumar MATCHER_P(EqualsRecord, Want, "") {
2586dd6a616SSnehasish Kumar const memprof::MemProfRecord &Got = arg;
2596dd6a616SSnehasish Kumar
__anon741d935d0602() 2606dd6a616SSnehasish Kumar auto PrintAndFail = [&]() {
2616dd6a616SSnehasish Kumar std::string Buffer;
2626dd6a616SSnehasish Kumar llvm::raw_string_ostream OS(Buffer);
2636dd6a616SSnehasish Kumar OS << "Want:\n";
2646dd6a616SSnehasish Kumar Want.print(OS);
2656dd6a616SSnehasish Kumar OS << "Got:\n";
2666dd6a616SSnehasish Kumar Got.print(OS);
2676dd6a616SSnehasish Kumar OS.flush();
2686dd6a616SSnehasish Kumar *result_listener << "MemProf Record differs!\n" << Buffer;
2696dd6a616SSnehasish Kumar return false;
2706dd6a616SSnehasish Kumar };
2716dd6a616SSnehasish Kumar
2726dd6a616SSnehasish Kumar if (Want.AllocSites.size() != Got.AllocSites.size())
2736dd6a616SSnehasish Kumar return PrintAndFail();
2746dd6a616SSnehasish Kumar if (Want.CallSites.size() != Got.CallSites.size())
2756dd6a616SSnehasish Kumar return PrintAndFail();
2766dd6a616SSnehasish Kumar
2776dd6a616SSnehasish Kumar for (size_t I = 0; I < Got.AllocSites.size(); I++) {
2786dd6a616SSnehasish Kumar if (Want.AllocSites[I].Info != Got.AllocSites[I].Info)
2796dd6a616SSnehasish Kumar return PrintAndFail();
2806dd6a616SSnehasish Kumar if (Want.AllocSites[I].CallStack != Got.AllocSites[I].CallStack)
2816dd6a616SSnehasish Kumar return PrintAndFail();
2826dd6a616SSnehasish Kumar }
2836dd6a616SSnehasish Kumar
2846dd6a616SSnehasish Kumar for (size_t I = 0; I < Got.CallSites.size(); I++) {
2856dd6a616SSnehasish Kumar if (Want.CallSites[I] != Got.CallSites[I])
2866dd6a616SSnehasish Kumar return PrintAndFail();
2876dd6a616SSnehasish Kumar }
2886dd6a616SSnehasish Kumar return true;
2896dd6a616SSnehasish Kumar }
2906dd6a616SSnehasish Kumar
TEST_F(InstrProfTest,test_memprof)2910a418490SSnehasish Kumar TEST_F(InstrProfTest, test_memprof) {
2920a418490SSnehasish Kumar ASSERT_THAT_ERROR(Writer.mergeProfileKind(InstrProfKind::MemProf),
2930a418490SSnehasish Kumar Succeeded());
29427a4f254SSnehasish Kumar
2956dd6a616SSnehasish Kumar const IndexedMemProfRecord IndexedMR = makeRecord(
29627a4f254SSnehasish Kumar /*AllocFrames=*/
29727a4f254SSnehasish Kumar {
2986dd6a616SSnehasish Kumar {0, 1},
2996dd6a616SSnehasish Kumar {2, 3},
30027a4f254SSnehasish Kumar },
30127a4f254SSnehasish Kumar /*CallSiteFrames=*/{
3026dd6a616SSnehasish Kumar {4, 5},
30327a4f254SSnehasish Kumar });
3046dd6a616SSnehasish Kumar const FrameIdMapTy IdToFrameMap = getFrameMapping();
3056dd6a616SSnehasish Kumar for (const auto &I : IdToFrameMap) {
3066dd6a616SSnehasish Kumar Writer.addMemProfFrame(I.first, I.getSecond(), Err);
3076dd6a616SSnehasish Kumar }
3086dd6a616SSnehasish Kumar Writer.addMemProfRecord(/*Id=*/0x9999, IndexedMR);
3090a418490SSnehasish Kumar
3100a418490SSnehasish Kumar auto Profile = Writer.writeBuffer();
3110a418490SSnehasish Kumar readProfile(std::move(Profile));
3120a418490SSnehasish Kumar
3136dd6a616SSnehasish Kumar auto RecordOr = Reader->getMemProfRecord(0x9999);
3146dd6a616SSnehasish Kumar ASSERT_THAT_ERROR(RecordOr.takeError(), Succeeded());
3156dd6a616SSnehasish Kumar const memprof::MemProfRecord &Record = RecordOr.get();
3166dd6a616SSnehasish Kumar
3176dd6a616SSnehasish Kumar memprof::FrameId LastUnmappedFrameId = 0;
3186dd6a616SSnehasish Kumar bool HasFrameMappingError = false;
3196dd6a616SSnehasish Kumar auto IdToFrameCallback = [&](const memprof::FrameId Id) {
3206dd6a616SSnehasish Kumar auto Iter = IdToFrameMap.find(Id);
3216dd6a616SSnehasish Kumar if (Iter == IdToFrameMap.end()) {
3226dd6a616SSnehasish Kumar LastUnmappedFrameId = Id;
3236dd6a616SSnehasish Kumar HasFrameMappingError = true;
3246dd6a616SSnehasish Kumar return memprof::Frame(0, 0, 0, false);
3256dd6a616SSnehasish Kumar }
3266dd6a616SSnehasish Kumar return Iter->second;
3276dd6a616SSnehasish Kumar };
3286dd6a616SSnehasish Kumar
3296dd6a616SSnehasish Kumar const memprof::MemProfRecord WantRecord(IndexedMR, IdToFrameCallback);
3306dd6a616SSnehasish Kumar ASSERT_FALSE(HasFrameMappingError)
3316dd6a616SSnehasish Kumar << "could not map frame id: " << LastUnmappedFrameId;
3326dd6a616SSnehasish Kumar EXPECT_THAT(WantRecord, EqualsRecord(Record));
3336dd6a616SSnehasish Kumar }
3346dd6a616SSnehasish Kumar
TEST_F(InstrProfTest,test_memprof_getrecord_error)3356dd6a616SSnehasish Kumar TEST_F(InstrProfTest, test_memprof_getrecord_error) {
3366dd6a616SSnehasish Kumar ASSERT_THAT_ERROR(Writer.mergeProfileKind(InstrProfKind::MemProf),
3376dd6a616SSnehasish Kumar Succeeded());
3386dd6a616SSnehasish Kumar
3396dd6a616SSnehasish Kumar const IndexedMemProfRecord IndexedMR = makeRecord(
3406dd6a616SSnehasish Kumar /*AllocFrames=*/
3416dd6a616SSnehasish Kumar {
3426dd6a616SSnehasish Kumar {0, 1},
3436dd6a616SSnehasish Kumar {2, 3},
3446dd6a616SSnehasish Kumar },
3456dd6a616SSnehasish Kumar /*CallSiteFrames=*/{
3466dd6a616SSnehasish Kumar {4, 5},
3476dd6a616SSnehasish Kumar });
3486dd6a616SSnehasish Kumar // We skip adding the frame mappings here unlike the test_memprof unit test
3496dd6a616SSnehasish Kumar // above to exercise the failure path when getMemProfRecord is invoked.
3506dd6a616SSnehasish Kumar Writer.addMemProfRecord(/*Id=*/0x9999, IndexedMR);
3516dd6a616SSnehasish Kumar
3526dd6a616SSnehasish Kumar auto Profile = Writer.writeBuffer();
3536dd6a616SSnehasish Kumar readProfile(std::move(Profile));
3546dd6a616SSnehasish Kumar
35565529486STeresa Johnson // Missing frames give a hash_mismatch error.
3566dd6a616SSnehasish Kumar auto RecordOr = Reader->getMemProfRecord(0x9999);
35765529486STeresa Johnson ASSERT_TRUE(
35865529486STeresa Johnson ErrorEquals(instrprof_error::hash_mismatch, RecordOr.takeError()));
35965529486STeresa Johnson
36065529486STeresa Johnson // Missing functions give a unknown_function error.
36165529486STeresa Johnson RecordOr = Reader->getMemProfRecord(0x1111);
36265529486STeresa Johnson ASSERT_TRUE(
36365529486STeresa Johnson ErrorEquals(instrprof_error::unknown_function, RecordOr.takeError()));
3640a418490SSnehasish Kumar }
3650a418490SSnehasish Kumar
TEST_F(InstrProfTest,test_memprof_merge)3660a418490SSnehasish Kumar TEST_F(InstrProfTest, test_memprof_merge) {
3670a418490SSnehasish Kumar Writer.addRecord({"func1", 0x1234, {42}}, Err);
3680a418490SSnehasish Kumar
3690a418490SSnehasish Kumar InstrProfWriter Writer2;
3700a418490SSnehasish Kumar ASSERT_THAT_ERROR(Writer2.mergeProfileKind(InstrProfKind::MemProf),
3710a418490SSnehasish Kumar Succeeded());
3720a418490SSnehasish Kumar
3736dd6a616SSnehasish Kumar const IndexedMemProfRecord IndexedMR = makeRecord(
37427a4f254SSnehasish Kumar /*AllocFrames=*/
37527a4f254SSnehasish Kumar {
3766dd6a616SSnehasish Kumar {0, 1},
3776dd6a616SSnehasish Kumar {2, 3},
37827a4f254SSnehasish Kumar },
37927a4f254SSnehasish Kumar /*CallSiteFrames=*/{
3806dd6a616SSnehasish Kumar {4, 5},
38127a4f254SSnehasish Kumar });
3826dd6a616SSnehasish Kumar
3836dd6a616SSnehasish Kumar const FrameIdMapTy IdToFrameMap = getFrameMapping();
3846dd6a616SSnehasish Kumar for (const auto &I : IdToFrameMap) {
3856dd6a616SSnehasish Kumar Writer.addMemProfFrame(I.first, I.getSecond(), Err);
3866dd6a616SSnehasish Kumar }
3876dd6a616SSnehasish Kumar Writer2.addMemProfRecord(/*Id=*/0x9999, IndexedMR);
3880a418490SSnehasish Kumar
3890a418490SSnehasish Kumar ASSERT_THAT_ERROR(Writer.mergeProfileKind(Writer2.getProfileKind()),
3900a418490SSnehasish Kumar Succeeded());
3910a418490SSnehasish Kumar Writer.mergeRecordsFromWriter(std::move(Writer2), Err);
3920a418490SSnehasish Kumar
3930a418490SSnehasish Kumar auto Profile = Writer.writeBuffer();
3940a418490SSnehasish Kumar readProfile(std::move(Profile));
3950a418490SSnehasish Kumar
3960a418490SSnehasish Kumar Expected<InstrProfRecord> R = Reader->getInstrProfRecord("func1", 0x1234);
3970a418490SSnehasish Kumar EXPECT_THAT_ERROR(R.takeError(), Succeeded());
3980a418490SSnehasish Kumar ASSERT_EQ(1U, R->Counts.size());
3990a418490SSnehasish Kumar ASSERT_EQ(42U, R->Counts[0]);
4000a418490SSnehasish Kumar
4016dd6a616SSnehasish Kumar auto RecordOr = Reader->getMemProfRecord(0x9999);
4026dd6a616SSnehasish Kumar ASSERT_THAT_ERROR(RecordOr.takeError(), Succeeded());
4036dd6a616SSnehasish Kumar const memprof::MemProfRecord &Record = RecordOr.get();
4046dd6a616SSnehasish Kumar
4056dd6a616SSnehasish Kumar memprof::FrameId LastUnmappedFrameId = 0;
4066dd6a616SSnehasish Kumar bool HasFrameMappingError = false;
4076dd6a616SSnehasish Kumar
4086dd6a616SSnehasish Kumar auto IdToFrameCallback = [&](const memprof::FrameId Id) {
4096dd6a616SSnehasish Kumar auto Iter = IdToFrameMap.find(Id);
4106dd6a616SSnehasish Kumar if (Iter == IdToFrameMap.end()) {
4116dd6a616SSnehasish Kumar LastUnmappedFrameId = Id;
4126dd6a616SSnehasish Kumar HasFrameMappingError = true;
4136dd6a616SSnehasish Kumar return memprof::Frame(0, 0, 0, false);
4146dd6a616SSnehasish Kumar }
4156dd6a616SSnehasish Kumar return Iter->second;
4166dd6a616SSnehasish Kumar };
4176dd6a616SSnehasish Kumar
4186dd6a616SSnehasish Kumar const memprof::MemProfRecord WantRecord(IndexedMR, IdToFrameCallback);
4196dd6a616SSnehasish Kumar ASSERT_FALSE(HasFrameMappingError)
4206dd6a616SSnehasish Kumar << "could not map frame id: " << LastUnmappedFrameId;
4216dd6a616SSnehasish Kumar EXPECT_THAT(WantRecord, EqualsRecord(Record));
4220a418490SSnehasish Kumar }
4230a418490SSnehasish Kumar
424a3e0d45bSXinliang David Li static const char callee1[] = "callee1";
425a3e0d45bSXinliang David Li static const char callee2[] = "callee2";
426a3e0d45bSXinliang David Li static const char callee3[] = "callee3";
427a3e0d45bSXinliang David Li static const char callee4[] = "callee4";
428a3e0d45bSXinliang David Li static const char callee5[] = "callee5";
429a3e0d45bSXinliang David Li static const char callee6[] = "callee6";
430a3e0d45bSXinliang David Li
TEST_P(MaybeSparseInstrProfTest,get_icall_data_read_write)43100dab228SVedant Kumar TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write) {
432cf9d52c6SDavid Blaikie NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
4332004f003SXinliang David Li
4342004f003SXinliang David Li // 4 value sites.
4352004f003SXinliang David Li Record1.reserveSites(IPVK_IndirectCallTarget, 4);
436a3e0d45bSXinliang David Li InstrProfValueData VD0[] = {
437a3e0d45bSXinliang David Li {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
438ffec81caSEugene Zelenko Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
439ee415895SXinliang David Li // No value profile data at the second site.
440ffec81caSEugene Zelenko Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
441a3e0d45bSXinliang David Li InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
442ffec81caSEugene Zelenko Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
443a3e0d45bSXinliang David Li InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
444ffec81caSEugene Zelenko Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
4452004f003SXinliang David Li
44698cce003SDavid Blaikie Writer.addRecord(std::move(Record1), Err);
44798cce003SDavid Blaikie Writer.addRecord({"callee1", 0x1235, {3, 4}}, Err);
44898cce003SDavid Blaikie Writer.addRecord({"callee2", 0x1235, {3, 4}}, Err);
44998cce003SDavid Blaikie Writer.addRecord({"callee3", 0x1235, {3, 4}}, Err);
4502004f003SXinliang David Li auto Profile = Writer.writeBuffer();
4512004f003SXinliang David Li readProfile(std::move(Profile));
4522004f003SXinliang David Li
4539152fd17SVedant Kumar Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
45494b98b2cSDavid Blaikie EXPECT_THAT_ERROR(R.takeError(), Succeeded());
455fed557efSDavid Blaikie ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
456fed557efSDavid Blaikie ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
457fed557efSDavid Blaikie ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
458fed557efSDavid Blaikie ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
459fed557efSDavid Blaikie ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
4602004f003SXinliang David Li
4611e4c809cSXinliang David Li uint64_t TotalC;
4622004f003SXinliang David Li std::unique_ptr<InstrProfValueData[]> VD =
463fed557efSDavid Blaikie R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC);
46451dc04cfSXinliang David Li
46551dc04cfSXinliang David Li ASSERT_EQ(3U, VD[0].Count);
46651dc04cfSXinliang David Li ASSERT_EQ(2U, VD[1].Count);
46751dc04cfSXinliang David Li ASSERT_EQ(1U, VD[2].Count);
4681e4c809cSXinliang David Li ASSERT_EQ(6U, TotalC);
46951dc04cfSXinliang David Li
47051dc04cfSXinliang David Li ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
47151dc04cfSXinliang David Li ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
47251dc04cfSXinliang David Li ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
47351dc04cfSXinliang David Li }
47451dc04cfSXinliang David Li
TEST_P(MaybeSparseInstrProfTest,annotate_vp_data)475402477d2SXinliang David Li TEST_P(MaybeSparseInstrProfTest, annotate_vp_data) {
476cf9d52c6SDavid Blaikie NamedInstrProfRecord Record("caller", 0x1234, {1, 2});
477402477d2SXinliang David Li Record.reserveSites(IPVK_IndirectCallTarget, 1);
47869683f13SRong Xu InstrProfValueData VD0[] = {{1000, 1}, {2000, 2}, {3000, 3}, {5000, 5},
47969683f13SRong Xu {4000, 4}, {6000, 6}};
48069683f13SRong Xu Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 6, nullptr);
48198cce003SDavid Blaikie Writer.addRecord(std::move(Record), Err);
482402477d2SXinliang David Li auto Profile = Writer.writeBuffer();
483402477d2SXinliang David Li readProfile(std::move(Profile));
4849152fd17SVedant Kumar Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
48594b98b2cSDavid Blaikie EXPECT_THAT_ERROR(R.takeError(), Succeeded());
486402477d2SXinliang David Li
487402477d2SXinliang David Li LLVMContext Ctx;
488402477d2SXinliang David Li std::unique_ptr<Module> M(new Module("MyModule", Ctx));
489402477d2SXinliang David Li FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
490402477d2SXinliang David Li /*isVarArg=*/false);
491402477d2SXinliang David Li Function *F =
492402477d2SXinliang David Li Function::Create(FTy, Function::ExternalLinkage, "caller", M.get());
493402477d2SXinliang David Li BasicBlock *BB = BasicBlock::Create(Ctx, "", F);
494402477d2SXinliang David Li
495402477d2SXinliang David Li IRBuilder<> Builder(BB);
496402477d2SXinliang David Li BasicBlock *TBB = BasicBlock::Create(Ctx, "", F);
497402477d2SXinliang David Li BasicBlock *FBB = BasicBlock::Create(Ctx, "", F);
498402477d2SXinliang David Li
499402477d2SXinliang David Li // Use branch instruction to annotate with value profile data for simplicity
500402477d2SXinliang David Li Instruction *Inst = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
501402477d2SXinliang David Li Instruction *Inst2 = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
502fed557efSDavid Blaikie annotateValueSite(*M, *Inst, R.get(), IPVK_IndirectCallTarget, 0);
503402477d2SXinliang David Li
504402477d2SXinliang David Li InstrProfValueData ValueData[5];
505402477d2SXinliang David Li uint32_t N;
506402477d2SXinliang David Li uint64_t T;
507402477d2SXinliang David Li bool Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
508402477d2SXinliang David Li ValueData, N, T);
509402477d2SXinliang David Li ASSERT_TRUE(Res);
510402477d2SXinliang David Li ASSERT_EQ(3U, N);
51169683f13SRong Xu ASSERT_EQ(21U, T);
512402477d2SXinliang David Li // The result should be sorted already:
51369683f13SRong Xu ASSERT_EQ(6000U, ValueData[0].Value);
51469683f13SRong Xu ASSERT_EQ(6U, ValueData[0].Count);
51569683f13SRong Xu ASSERT_EQ(5000U, ValueData[1].Value);
51669683f13SRong Xu ASSERT_EQ(5U, ValueData[1].Count);
51769683f13SRong Xu ASSERT_EQ(4000U, ValueData[2].Value);
51869683f13SRong Xu ASSERT_EQ(4U, ValueData[2].Count);
519402477d2SXinliang David Li Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 1, ValueData,
520402477d2SXinliang David Li N, T);
521402477d2SXinliang David Li ASSERT_TRUE(Res);
522402477d2SXinliang David Li ASSERT_EQ(1U, N);
52369683f13SRong Xu ASSERT_EQ(21U, T);
524402477d2SXinliang David Li
525402477d2SXinliang David Li Res = getValueProfDataFromInst(*Inst2, IPVK_IndirectCallTarget, 5, ValueData,
526402477d2SXinliang David Li N, T);
527402477d2SXinliang David Li ASSERT_FALSE(Res);
52869683f13SRong Xu
52969683f13SRong Xu // Remove the MD_prof metadata
53069683f13SRong Xu Inst->setMetadata(LLVMContext::MD_prof, 0);
53169683f13SRong Xu // Annotate 5 records this time.
53269683f13SRong Xu annotateValueSite(*M, *Inst, R.get(), IPVK_IndirectCallTarget, 0, 5);
53369683f13SRong Xu Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
53469683f13SRong Xu ValueData, N, T);
53569683f13SRong Xu ASSERT_TRUE(Res);
53669683f13SRong Xu ASSERT_EQ(5U, N);
53769683f13SRong Xu ASSERT_EQ(21U, T);
53869683f13SRong Xu ASSERT_EQ(6000U, ValueData[0].Value);
53969683f13SRong Xu ASSERT_EQ(6U, ValueData[0].Count);
54069683f13SRong Xu ASSERT_EQ(5000U, ValueData[1].Value);
54169683f13SRong Xu ASSERT_EQ(5U, ValueData[1].Count);
54269683f13SRong Xu ASSERT_EQ(4000U, ValueData[2].Value);
54369683f13SRong Xu ASSERT_EQ(4U, ValueData[2].Count);
54469683f13SRong Xu ASSERT_EQ(3000U, ValueData[3].Value);
54569683f13SRong Xu ASSERT_EQ(3U, ValueData[3].Count);
54669683f13SRong Xu ASSERT_EQ(2000U, ValueData[4].Value);
54769683f13SRong Xu ASSERT_EQ(2U, ValueData[4].Count);
548bb49490dSRong Xu
549bb49490dSRong Xu // Remove the MD_prof metadata
550bb49490dSRong Xu Inst->setMetadata(LLVMContext::MD_prof, 0);
551bb49490dSRong Xu // Annotate with 4 records.
552bb49490dSRong Xu InstrProfValueData VD0Sorted[] = {{1000, 6}, {2000, 5}, {3000, 4}, {4000, 3},
553bb49490dSRong Xu {5000, 2}, {6000, 1}};
554311ada11SRong Xu annotateValueSite(*M, *Inst, makeArrayRef(VD0Sorted).slice(2), 10,
555311ada11SRong Xu IPVK_IndirectCallTarget, 5);
556bb49490dSRong Xu Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
557bb49490dSRong Xu ValueData, N, T);
558bb49490dSRong Xu ASSERT_TRUE(Res);
559bb49490dSRong Xu ASSERT_EQ(4U, N);
560bb49490dSRong Xu ASSERT_EQ(10U, T);
561bb49490dSRong Xu ASSERT_EQ(3000U, ValueData[0].Value);
562bb49490dSRong Xu ASSERT_EQ(4U, ValueData[0].Count);
563bb49490dSRong Xu ASSERT_EQ(4000U, ValueData[1].Value);
564bb49490dSRong Xu ASSERT_EQ(3U, ValueData[1].Count);
565bb49490dSRong Xu ASSERT_EQ(5000U, ValueData[2].Value);
566bb49490dSRong Xu ASSERT_EQ(2U, ValueData[2].Count);
567bb49490dSRong Xu ASSERT_EQ(6000U, ValueData[3].Value);
568bb49490dSRong Xu ASSERT_EQ(1U, ValueData[3].Count);
569402477d2SXinliang David Li }
570402477d2SXinliang David Li
TEST_P(MaybeSparseInstrProfTest,get_icall_data_read_write_with_weight)57100dab228SVedant Kumar TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_with_weight) {
572cf9d52c6SDavid Blaikie NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
57351dc04cfSXinliang David Li
57451dc04cfSXinliang David Li // 4 value sites.
57551dc04cfSXinliang David Li Record1.reserveSites(IPVK_IndirectCallTarget, 4);
576a3e0d45bSXinliang David Li InstrProfValueData VD0[] = {
577a3e0d45bSXinliang David Li {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
57851dc04cfSXinliang David Li Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
57951dc04cfSXinliang David Li // No value profile data at the second site.
58051dc04cfSXinliang David Li Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
581a3e0d45bSXinliang David Li InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
58251dc04cfSXinliang David Li Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
583a3e0d45bSXinliang David Li InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
58451dc04cfSXinliang David Li Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
58551dc04cfSXinliang David Li
58698cce003SDavid Blaikie Writer.addRecord(std::move(Record1), 10, Err);
58798cce003SDavid Blaikie Writer.addRecord({"callee1", 0x1235, {3, 4}}, Err);
58898cce003SDavid Blaikie Writer.addRecord({"callee2", 0x1235, {3, 4}}, Err);
58998cce003SDavid Blaikie Writer.addRecord({"callee3", 0x1235, {3, 4}}, Err);
59051dc04cfSXinliang David Li auto Profile = Writer.writeBuffer();
59151dc04cfSXinliang David Li readProfile(std::move(Profile));
59251dc04cfSXinliang David Li
5939152fd17SVedant Kumar Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
59494b98b2cSDavid Blaikie EXPECT_THAT_ERROR(R.takeError(), Succeeded());
595fed557efSDavid Blaikie ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
596fed557efSDavid Blaikie ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
597fed557efSDavid Blaikie ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
598fed557efSDavid Blaikie ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
599fed557efSDavid Blaikie ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
60051dc04cfSXinliang David Li
6011e4c809cSXinliang David Li uint64_t TotalC;
60251dc04cfSXinliang David Li std::unique_ptr<InstrProfValueData[]> VD =
603fed557efSDavid Blaikie R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC);
60451dc04cfSXinliang David Li ASSERT_EQ(30U, VD[0].Count);
60551dc04cfSXinliang David Li ASSERT_EQ(20U, VD[1].Count);
60651dc04cfSXinliang David Li ASSERT_EQ(10U, VD[2].Count);
6071e4c809cSXinliang David Li ASSERT_EQ(60U, TotalC);
60851dc04cfSXinliang David Li
6092004f003SXinliang David Li ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
6102004f003SXinliang David Li ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
6112004f003SXinliang David Li ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
6122004f003SXinliang David Li }
6132004f003SXinliang David Li
TEST_P(MaybeSparseInstrProfTest,get_icall_data_read_write_big_endian)61400dab228SVedant Kumar TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_big_endian) {
615cf9d52c6SDavid Blaikie NamedInstrProfRecord Record1("caller", 0x1234, {1, 2});
61646ad363bSXinliang David Li
61746ad363bSXinliang David Li // 4 value sites.
61846ad363bSXinliang David Li Record1.reserveSites(IPVK_IndirectCallTarget, 4);
619a3e0d45bSXinliang David Li InstrProfValueData VD0[] = {
620a3e0d45bSXinliang David Li {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}};
62146ad363bSXinliang David Li Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
62246ad363bSXinliang David Li // No value profile data at the second site.
62346ad363bSXinliang David Li Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
624a3e0d45bSXinliang David Li InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}};
62546ad363bSXinliang David Li Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
626a3e0d45bSXinliang David Li InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}};
62746ad363bSXinliang David Li Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
62846ad363bSXinliang David Li
62998cce003SDavid Blaikie Writer.addRecord(std::move(Record1), Err);
63098cce003SDavid Blaikie Writer.addRecord({"callee1", 0x1235, {3, 4}}, Err);
63198cce003SDavid Blaikie Writer.addRecord({"callee2", 0x1235, {3, 4}}, Err);
63298cce003SDavid Blaikie Writer.addRecord({"callee3", 0x1235, {3, 4}}, Err);
63346ad363bSXinliang David Li
63446ad363bSXinliang David Li // Set big endian output.
63546ad363bSXinliang David Li Writer.setValueProfDataEndianness(support::big);
63646ad363bSXinliang David Li
63746ad363bSXinliang David Li auto Profile = Writer.writeBuffer();
63846ad363bSXinliang David Li readProfile(std::move(Profile));
63946ad363bSXinliang David Li
64046ad363bSXinliang David Li // Set big endian input.
64146ad363bSXinliang David Li Reader->setValueProfDataEndianness(support::big);
64246ad363bSXinliang David Li
6439152fd17SVedant Kumar Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
64494b98b2cSDavid Blaikie EXPECT_THAT_ERROR(R.takeError(), Succeeded());
645fed557efSDavid Blaikie ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget));
646fed557efSDavid Blaikie ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
647fed557efSDavid Blaikie ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
648fed557efSDavid Blaikie ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
649fed557efSDavid Blaikie ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
65046ad363bSXinliang David Li
65146ad363bSXinliang David Li std::unique_ptr<InstrProfValueData[]> VD =
652fed557efSDavid Blaikie R->getValueForSite(IPVK_IndirectCallTarget, 0);
65346ad363bSXinliang David Li ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
65446ad363bSXinliang David Li ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
65546ad363bSXinliang David Li ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
65646ad363bSXinliang David Li
65746ad363bSXinliang David Li // Restore little endian default:
65846ad363bSXinliang David Li Writer.setValueProfDataEndianness(support::little);
65946ad363bSXinliang David Li }
66046ad363bSXinliang David Li
TEST_P(MaybeSparseInstrProfTest,get_icall_data_merge1)66100dab228SVedant Kumar TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge1) {
6627345ac0cSNAKAMURA Takumi static const char caller[] = "caller";
663cf9d52c6SDavid Blaikie NamedInstrProfRecord Record11(caller, 0x1234, {1, 2});
664cf9d52c6SDavid Blaikie NamedInstrProfRecord Record12(caller, 0x1234, {1, 2});
6652004f003SXinliang David Li
6662004f003SXinliang David Li // 5 value sites.
6672004f003SXinliang David Li Record11.reserveSites(IPVK_IndirectCallTarget, 5);
6687345ac0cSNAKAMURA Takumi InstrProfValueData VD0[] = {{uint64_t(callee1), 1},
6697345ac0cSNAKAMURA Takumi {uint64_t(callee2), 2},
6707345ac0cSNAKAMURA Takumi {uint64_t(callee3), 3},
6717345ac0cSNAKAMURA Takumi {uint64_t(callee4), 4}};
672ffec81caSEugene Zelenko Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 4, nullptr);
6732004f003SXinliang David Li
674872df22cSXinliang David Li // No value profile data at the second site.
675ffec81caSEugene Zelenko Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
6762004f003SXinliang David Li
677872df22cSXinliang David Li InstrProfValueData VD2[] = {
678872df22cSXinliang David Li {uint64_t(callee1), 1}, {uint64_t(callee2), 2}, {uint64_t(callee3), 3}};
679ffec81caSEugene Zelenko Record11.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr);
6802004f003SXinliang David Li
6817345ac0cSNAKAMURA Takumi InstrProfValueData VD3[] = {{uint64_t(callee1), 1}};
682ffec81caSEugene Zelenko Record11.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
6832004f003SXinliang David Li
6847345ac0cSNAKAMURA Takumi InstrProfValueData VD4[] = {{uint64_t(callee1), 1},
6857345ac0cSNAKAMURA Takumi {uint64_t(callee2), 2},
6867345ac0cSNAKAMURA Takumi {uint64_t(callee3), 3}};
687ffec81caSEugene Zelenko Record11.addValueData(IPVK_IndirectCallTarget, 4, VD4, 3, nullptr);
6882004f003SXinliang David Li
68968318e04SDavid Majnemer // A different record for the same caller.
6902004f003SXinliang David Li Record12.reserveSites(IPVK_IndirectCallTarget, 5);
691872df22cSXinliang David Li InstrProfValueData VD02[] = {{uint64_t(callee2), 5}, {uint64_t(callee3), 3}};
692ffec81caSEugene Zelenko Record12.addValueData(IPVK_IndirectCallTarget, 0, VD02, 2, nullptr);
6932004f003SXinliang David Li
694872df22cSXinliang David Li // No value profile data at the second site.
695ffec81caSEugene Zelenko Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
6962004f003SXinliang David Li
697872df22cSXinliang David Li InstrProfValueData VD22[] = {
698872df22cSXinliang David Li {uint64_t(callee2), 1}, {uint64_t(callee3), 3}, {uint64_t(callee4), 4}};
699ffec81caSEugene Zelenko Record12.addValueData(IPVK_IndirectCallTarget, 2, VD22, 3, nullptr);
7002004f003SXinliang David Li
701ffec81caSEugene Zelenko Record12.addValueData(IPVK_IndirectCallTarget, 3, nullptr, 0, nullptr);
7022004f003SXinliang David Li
70346ad363bSXinliang David Li InstrProfValueData VD42[] = {{uint64_t(callee1), 1},
70446ad363bSXinliang David Li {uint64_t(callee2), 2},
70546ad363bSXinliang David Li {uint64_t(callee3), 3}};
706ffec81caSEugene Zelenko Record12.addValueData(IPVK_IndirectCallTarget, 4, VD42, 3, nullptr);
7072004f003SXinliang David Li
70898cce003SDavid Blaikie Writer.addRecord(std::move(Record11), Err);
7092004f003SXinliang David Li // Merge profile data.
71098cce003SDavid Blaikie Writer.addRecord(std::move(Record12), Err);
7112004f003SXinliang David Li
71298cce003SDavid Blaikie Writer.addRecord({callee1, 0x1235, {3, 4}}, Err);
71398cce003SDavid Blaikie Writer.addRecord({callee2, 0x1235, {3, 4}}, Err);
71498cce003SDavid Blaikie Writer.addRecord({callee3, 0x1235, {3, 4}}, Err);
71598cce003SDavid Blaikie Writer.addRecord({callee3, 0x1235, {3, 4}}, Err);
71698cce003SDavid Blaikie Writer.addRecord({callee4, 0x1235, {3, 5}}, Err);
7172004f003SXinliang David Li auto Profile = Writer.writeBuffer();
7182004f003SXinliang David Li readProfile(std::move(Profile));
7192004f003SXinliang David Li
7209152fd17SVedant Kumar Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
72194b98b2cSDavid Blaikie EXPECT_THAT_ERROR(R.takeError(), Succeeded());
722fed557efSDavid Blaikie ASSERT_EQ(5U, R->getNumValueSites(IPVK_IndirectCallTarget));
723fed557efSDavid Blaikie ASSERT_EQ(4U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
724fed557efSDavid Blaikie ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
725fed557efSDavid Blaikie ASSERT_EQ(4U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
726fed557efSDavid Blaikie ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
727fed557efSDavid Blaikie ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 4));
7282004f003SXinliang David Li
7292004f003SXinliang David Li std::unique_ptr<InstrProfValueData[]> VD =
730fed557efSDavid Blaikie R->getValueForSite(IPVK_IndirectCallTarget, 0);
7312004f003SXinliang David Li ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee2"));
7322004f003SXinliang David Li ASSERT_EQ(7U, VD[0].Count);
7332004f003SXinliang David Li ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee3"));
7342004f003SXinliang David Li ASSERT_EQ(6U, VD[1].Count);
7352004f003SXinliang David Li ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee4"));
7362004f003SXinliang David Li ASSERT_EQ(4U, VD[2].Count);
7372004f003SXinliang David Li ASSERT_EQ(StringRef((const char *)VD[3].Value, 7), StringRef("callee1"));
7382004f003SXinliang David Li ASSERT_EQ(1U, VD[3].Count);
7392004f003SXinliang David Li
7402004f003SXinliang David Li std::unique_ptr<InstrProfValueData[]> VD_2(
741fed557efSDavid Blaikie R->getValueForSite(IPVK_IndirectCallTarget, 2));
7422004f003SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee3"));
7432004f003SXinliang David Li ASSERT_EQ(6U, VD_2[0].Count);
7442004f003SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_2[1].Value, 7), StringRef("callee4"));
7452004f003SXinliang David Li ASSERT_EQ(4U, VD_2[1].Count);
7462004f003SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_2[2].Value, 7), StringRef("callee2"));
7472004f003SXinliang David Li ASSERT_EQ(3U, VD_2[2].Count);
7482004f003SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_2[3].Value, 7), StringRef("callee1"));
7492004f003SXinliang David Li ASSERT_EQ(1U, VD_2[3].Count);
7502004f003SXinliang David Li
7512004f003SXinliang David Li std::unique_ptr<InstrProfValueData[]> VD_3(
752fed557efSDavid Blaikie R->getValueForSite(IPVK_IndirectCallTarget, 3));
7532004f003SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee1"));
7542004f003SXinliang David Li ASSERT_EQ(1U, VD_3[0].Count);
7552004f003SXinliang David Li
7562004f003SXinliang David Li std::unique_ptr<InstrProfValueData[]> VD_4(
757fed557efSDavid Blaikie R->getValueForSite(IPVK_IndirectCallTarget, 4));
7582004f003SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_4[0].Value, 7), StringRef("callee3"));
7592004f003SXinliang David Li ASSERT_EQ(6U, VD_4[0].Count);
7602004f003SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_4[1].Value, 7), StringRef("callee2"));
7612004f003SXinliang David Li ASSERT_EQ(4U, VD_4[1].Count);
7622004f003SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_4[2].Value, 7), StringRef("callee1"));
7632004f003SXinliang David Li ASSERT_EQ(2U, VD_4[2].Count);
7642004f003SXinliang David Li }
7652004f003SXinliang David Li
TEST_P(MaybeSparseInstrProfTest,get_icall_data_merge1_saturation)76600dab228SVedant Kumar TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge1_saturation) {
7677345ac0cSNAKAMURA Takumi static const char bar[] = "bar";
7687345ac0cSNAKAMURA Takumi
769be9db3c0SDaniel Sanders const uint64_t Max = std::numeric_limits<uint64_t>::max();
770be9db3c0SDaniel Sanders
77198cce003SDavid Blaikie instrprof_error Result;
77298cce003SDavid Blaikie auto Err = [&](Error E) { Result = InstrProfError::take(std::move(E)); };
77398cce003SDavid Blaikie Result = instrprof_error::success;
77498cce003SDavid Blaikie Writer.addRecord({"foo", 0x1234, {1}}, Err);
77598cce003SDavid Blaikie ASSERT_EQ(Result, instrprof_error::success);
776be9db3c0SDaniel Sanders
77748dd080cSNathan Slingerland // Verify counter overflow.
77898cce003SDavid Blaikie Result = instrprof_error::success;
77998cce003SDavid Blaikie Writer.addRecord({"foo", 0x1234, {Max}}, Err);
78098cce003SDavid Blaikie ASSERT_EQ(Result, instrprof_error::counter_overflow);
781be9db3c0SDaniel Sanders
78298cce003SDavid Blaikie Result = instrprof_error::success;
78398cce003SDavid Blaikie Writer.addRecord({bar, 0x9012, {8}}, Err);
78498cce003SDavid Blaikie ASSERT_EQ(Result, instrprof_error::success);
785be9db3c0SDaniel Sanders
786cf9d52c6SDavid Blaikie NamedInstrProfRecord Record4("baz", 0x5678, {3, 4});
78748dd080cSNathan Slingerland Record4.reserveSites(IPVK_IndirectCallTarget, 1);
7887345ac0cSNAKAMURA Takumi InstrProfValueData VD4[] = {{uint64_t(bar), 1}};
78948dd080cSNathan Slingerland Record4.addValueData(IPVK_IndirectCallTarget, 0, VD4, 1, nullptr);
79098cce003SDavid Blaikie Result = instrprof_error::success;
79198cce003SDavid Blaikie Writer.addRecord(std::move(Record4), Err);
79298cce003SDavid Blaikie ASSERT_EQ(Result, instrprof_error::success);
79348dd080cSNathan Slingerland
79448dd080cSNathan Slingerland // Verify value data counter overflow.
795cf9d52c6SDavid Blaikie NamedInstrProfRecord Record5("baz", 0x5678, {5, 6});
79648dd080cSNathan Slingerland Record5.reserveSites(IPVK_IndirectCallTarget, 1);
7977345ac0cSNAKAMURA Takumi InstrProfValueData VD5[] = {{uint64_t(bar), Max}};
79848dd080cSNathan Slingerland Record5.addValueData(IPVK_IndirectCallTarget, 0, VD5, 1, nullptr);
79998cce003SDavid Blaikie Result = instrprof_error::success;
80098cce003SDavid Blaikie Writer.addRecord(std::move(Record5), Err);
80198cce003SDavid Blaikie ASSERT_EQ(Result, instrprof_error::counter_overflow);
802be9db3c0SDaniel Sanders
803be9db3c0SDaniel Sanders auto Profile = Writer.writeBuffer();
804be9db3c0SDaniel Sanders readProfile(std::move(Profile));
805be9db3c0SDaniel Sanders
806be9db3c0SDaniel Sanders // Verify saturation of counts.
8079152fd17SVedant Kumar Expected<InstrProfRecord> ReadRecord1 =
80848dd080cSNathan Slingerland Reader->getInstrProfRecord("foo", 0x1234);
80994b98b2cSDavid Blaikie EXPECT_THAT_ERROR(ReadRecord1.takeError(), Succeeded());
810fed557efSDavid Blaikie ASSERT_EQ(Max, ReadRecord1->Counts[0]);
811aa5702d9SNathan Slingerland
8129152fd17SVedant Kumar Expected<InstrProfRecord> ReadRecord2 =
81348dd080cSNathan Slingerland Reader->getInstrProfRecord("baz", 0x5678);
8149152fd17SVedant Kumar ASSERT_TRUE(bool(ReadRecord2));
815fed557efSDavid Blaikie ASSERT_EQ(1U, ReadRecord2->getNumValueSites(IPVK_IndirectCallTarget));
816be9db3c0SDaniel Sanders std::unique_ptr<InstrProfValueData[]> VD =
817fed557efSDavid Blaikie ReadRecord2->getValueForSite(IPVK_IndirectCallTarget, 0);
81848dd080cSNathan Slingerland ASSERT_EQ(StringRef("bar"), StringRef((const char *)VD[0].Value, 3));
81948dd080cSNathan Slingerland ASSERT_EQ(Max, VD[0].Count);
820be9db3c0SDaniel Sanders }
821be9db3c0SDaniel Sanders
822872df22cSXinliang David Li // This test tests that when there are too many values
823872df22cSXinliang David Li // for a given site, the merged results are properly
824872df22cSXinliang David Li // truncated.
TEST_P(MaybeSparseInstrProfTest,get_icall_data_merge_site_trunc)82500dab228SVedant Kumar TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge_site_trunc) {
826872df22cSXinliang David Li static const char caller[] = "caller";
827872df22cSXinliang David Li
828cf9d52c6SDavid Blaikie NamedInstrProfRecord Record11(caller, 0x1234, {1, 2});
829cf9d52c6SDavid Blaikie NamedInstrProfRecord Record12(caller, 0x1234, {1, 2});
830872df22cSXinliang David Li
831872df22cSXinliang David Li // 2 value sites.
832872df22cSXinliang David Li Record11.reserveSites(IPVK_IndirectCallTarget, 2);
833872df22cSXinliang David Li InstrProfValueData VD0[255];
834872df22cSXinliang David Li for (int I = 0; I < 255; I++) {
835872df22cSXinliang David Li VD0[I].Value = 2 * I;
836872df22cSXinliang David Li VD0[I].Count = 2 * I + 1000;
837872df22cSXinliang David Li }
838872df22cSXinliang David Li
839872df22cSXinliang David Li Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 255, nullptr);
840872df22cSXinliang David Li Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
841872df22cSXinliang David Li
842872df22cSXinliang David Li Record12.reserveSites(IPVK_IndirectCallTarget, 2);
843872df22cSXinliang David Li InstrProfValueData VD1[255];
844872df22cSXinliang David Li for (int I = 0; I < 255; I++) {
845872df22cSXinliang David Li VD1[I].Value = 2 * I + 1;
846872df22cSXinliang David Li VD1[I].Count = 2 * I + 1001;
847872df22cSXinliang David Li }
848872df22cSXinliang David Li
849872df22cSXinliang David Li Record12.addValueData(IPVK_IndirectCallTarget, 0, VD1, 255, nullptr);
850872df22cSXinliang David Li Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
851872df22cSXinliang David Li
85298cce003SDavid Blaikie Writer.addRecord(std::move(Record11), Err);
853872df22cSXinliang David Li // Merge profile data.
85498cce003SDavid Blaikie Writer.addRecord(std::move(Record12), Err);
855872df22cSXinliang David Li
856872df22cSXinliang David Li auto Profile = Writer.writeBuffer();
857872df22cSXinliang David Li readProfile(std::move(Profile));
858872df22cSXinliang David Li
8599152fd17SVedant Kumar Expected<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
86094b98b2cSDavid Blaikie EXPECT_THAT_ERROR(R.takeError(), Succeeded());
861872df22cSXinliang David Li std::unique_ptr<InstrProfValueData[]> VD(
862fed557efSDavid Blaikie R->getValueForSite(IPVK_IndirectCallTarget, 0));
863fed557efSDavid Blaikie ASSERT_EQ(2U, R->getNumValueSites(IPVK_IndirectCallTarget));
864fed557efSDavid Blaikie ASSERT_EQ(255U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
865249edf3dSNAKAMURA Takumi for (unsigned I = 0; I < 255; I++) {
866872df22cSXinliang David Li ASSERT_EQ(VD[I].Value, 509 - I);
867872df22cSXinliang David Li ASSERT_EQ(VD[I].Count, 1509 - I);
868872df22cSXinliang David Li }
869872df22cSXinliang David Li }
870872df22cSXinliang David Li
addValueProfData(InstrProfRecord & Record)8718e6b917eSXinliang David Li static void addValueProfData(InstrProfRecord &Record) {
8728e6b917eSXinliang David Li Record.reserveSites(IPVK_IndirectCallTarget, 5);
8738e6b917eSXinliang David Li InstrProfValueData VD0[] = {{uint64_t(callee1), 400},
8748e6b917eSXinliang David Li {uint64_t(callee2), 1000},
8758e6b917eSXinliang David Li {uint64_t(callee3), 500},
8768e6b917eSXinliang David Li {uint64_t(callee4), 300},
8778e6b917eSXinliang David Li {uint64_t(callee5), 100}};
8788e6b917eSXinliang David Li Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 5, nullptr);
8798e6b917eSXinliang David Li InstrProfValueData VD1[] = {{uint64_t(callee5), 800},
8808e6b917eSXinliang David Li {uint64_t(callee3), 1000},
8818e6b917eSXinliang David Li {uint64_t(callee2), 2500},
8828e6b917eSXinliang David Li {uint64_t(callee1), 1300}};
8838e6b917eSXinliang David Li Record.addValueData(IPVK_IndirectCallTarget, 1, VD1, 4, nullptr);
8848e6b917eSXinliang David Li InstrProfValueData VD2[] = {{uint64_t(callee6), 800},
8858e6b917eSXinliang David Li {uint64_t(callee3), 1000},
8868e6b917eSXinliang David Li {uint64_t(callee4), 5500}};
8878e6b917eSXinliang David Li Record.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr);
8888e6b917eSXinliang David Li InstrProfValueData VD3[] = {{uint64_t(callee2), 1800},
8898e6b917eSXinliang David Li {uint64_t(callee3), 2000}};
8908e6b917eSXinliang David Li Record.addValueData(IPVK_IndirectCallTarget, 3, VD3, 2, nullptr);
8918e6b917eSXinliang David Li Record.addValueData(IPVK_IndirectCallTarget, 4, nullptr, 0, nullptr);
8928e6b917eSXinliang David Li }
893ed966771SXinliang David Li
TEST_P(MaybeSparseInstrProfTest,value_prof_data_read_write)8948e6b917eSXinliang David Li TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write) {
895cf9d52c6SDavid Blaikie InstrProfRecord SrcRecord({1ULL << 31, 2});
8968e6b917eSXinliang David Li addValueProfData(SrcRecord);
8978e6b917eSXinliang David Li std::unique_ptr<ValueProfData> VPData =
8988e6b917eSXinliang David Li ValueProfData::serializeFrom(SrcRecord);
899ed966771SXinliang David Li
900cf9d52c6SDavid Blaikie InstrProfRecord Record({1ULL << 31, 2});
9016ac3f739SEugene Zelenko VPData->deserializeTo(Record, nullptr);
902ed966771SXinliang David Li
903ed966771SXinliang David Li // Now read data from Record and sanity check the data
904ed966771SXinliang David Li ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget));
905ed966771SXinliang David Li ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
906ed966771SXinliang David Li ASSERT_EQ(4U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
907ed966771SXinliang David Li ASSERT_EQ(3U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
908ed966771SXinliang David Li ASSERT_EQ(2U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
909ed966771SXinliang David Li ASSERT_EQ(0U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 4));
910ed966771SXinliang David Li
911ed966771SXinliang David Li auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
912ed966771SXinliang David Li return VD1.Count > VD2.Count;
913ed966771SXinliang David Li };
914ed966771SXinliang David Li std::unique_ptr<InstrProfValueData[]> VD_0(
915ed966771SXinliang David Li Record.getValueForSite(IPVK_IndirectCallTarget, 0));
91613e70cb1SMandeep Singh Grang llvm::sort(&VD_0[0], &VD_0[5], Cmp);
917ed966771SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_0[0].Value, 7), StringRef("callee2"));
918ed966771SXinliang David Li ASSERT_EQ(1000U, VD_0[0].Count);
919ed966771SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_0[1].Value, 7), StringRef("callee3"));
920ed966771SXinliang David Li ASSERT_EQ(500U, VD_0[1].Count);
921ed966771SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_0[2].Value, 7), StringRef("callee1"));
922ed966771SXinliang David Li ASSERT_EQ(400U, VD_0[2].Count);
923ed966771SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_0[3].Value, 7), StringRef("callee4"));
924ed966771SXinliang David Li ASSERT_EQ(300U, VD_0[3].Count);
925ed966771SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_0[4].Value, 7), StringRef("callee5"));
926ed966771SXinliang David Li ASSERT_EQ(100U, VD_0[4].Count);
927ed966771SXinliang David Li
928ed966771SXinliang David Li std::unique_ptr<InstrProfValueData[]> VD_1(
929ed966771SXinliang David Li Record.getValueForSite(IPVK_IndirectCallTarget, 1));
93013e70cb1SMandeep Singh Grang llvm::sort(&VD_1[0], &VD_1[4], Cmp);
931ed966771SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_1[0].Value, 7), StringRef("callee2"));
932ed966771SXinliang David Li ASSERT_EQ(2500U, VD_1[0].Count);
933ed966771SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_1[1].Value, 7), StringRef("callee1"));
934ed966771SXinliang David Li ASSERT_EQ(1300U, VD_1[1].Count);
935ed966771SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_1[2].Value, 7), StringRef("callee3"));
936ed966771SXinliang David Li ASSERT_EQ(1000U, VD_1[2].Count);
937ed966771SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_1[3].Value, 7), StringRef("callee5"));
938ed966771SXinliang David Li ASSERT_EQ(800U, VD_1[3].Count);
939ed966771SXinliang David Li
940ed966771SXinliang David Li std::unique_ptr<InstrProfValueData[]> VD_2(
941ed966771SXinliang David Li Record.getValueForSite(IPVK_IndirectCallTarget, 2));
94213e70cb1SMandeep Singh Grang llvm::sort(&VD_2[0], &VD_2[3], Cmp);
943ed966771SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee4"));
944ed966771SXinliang David Li ASSERT_EQ(5500U, VD_2[0].Count);
945ed966771SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_2[1].Value, 7), StringRef("callee3"));
946ed966771SXinliang David Li ASSERT_EQ(1000U, VD_2[1].Count);
947ed966771SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_2[2].Value, 7), StringRef("callee6"));
948ed966771SXinliang David Li ASSERT_EQ(800U, VD_2[2].Count);
949ed966771SXinliang David Li
950ed966771SXinliang David Li std::unique_ptr<InstrProfValueData[]> VD_3(
951ed966771SXinliang David Li Record.getValueForSite(IPVK_IndirectCallTarget, 3));
95213e70cb1SMandeep Singh Grang llvm::sort(&VD_3[0], &VD_3[2], Cmp);
953ed966771SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee3"));
954ed966771SXinliang David Li ASSERT_EQ(2000U, VD_3[0].Count);
955ed966771SXinliang David Li ASSERT_EQ(StringRef((const char *)VD_3[1].Value, 7), StringRef("callee2"));
956ed966771SXinliang David Li ASSERT_EQ(1800U, VD_3[1].Count);
957ed966771SXinliang David Li }
958ed966771SXinliang David Li
TEST_P(MaybeSparseInstrProfTest,value_prof_data_read_write_mapping)9598e6b917eSXinliang David Li TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write_mapping) {
96028464483SXinliang David Li
961cf9d52c6SDavid Blaikie NamedInstrProfRecord SrcRecord("caller", 0x1234, {1ULL << 31, 2});
9628e6b917eSXinliang David Li addValueProfData(SrcRecord);
9638e6b917eSXinliang David Li std::unique_ptr<ValueProfData> VPData =
9648e6b917eSXinliang David Li ValueProfData::serializeFrom(SrcRecord);
96528464483SXinliang David Li
966cf9d52c6SDavid Blaikie NamedInstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2});
96728464483SXinliang David Li InstrProfSymtab Symtab;
96828464483SXinliang David Li Symtab.mapAddress(uint64_t(callee1), 0x1000ULL);
96928464483SXinliang David Li Symtab.mapAddress(uint64_t(callee2), 0x2000ULL);
97028464483SXinliang David Li Symtab.mapAddress(uint64_t(callee3), 0x3000ULL);
97128464483SXinliang David Li Symtab.mapAddress(uint64_t(callee4), 0x4000ULL);
97228464483SXinliang David Li // Missing mapping for callee5
97328464483SXinliang David Li
974556f8f6aSMircea Trofin VPData->deserializeTo(Record, &Symtab);
97528464483SXinliang David Li
97628464483SXinliang David Li // Now read data from Record and sanity check the data
9778e6b917eSXinliang David Li ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget));
97828464483SXinliang David Li ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
97928464483SXinliang David Li
98028464483SXinliang David Li auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
98128464483SXinliang David Li return VD1.Count > VD2.Count;
98228464483SXinliang David Li };
98328464483SXinliang David Li std::unique_ptr<InstrProfValueData[]> VD_0(
98428464483SXinliang David Li Record.getValueForSite(IPVK_IndirectCallTarget, 0));
98513e70cb1SMandeep Singh Grang llvm::sort(&VD_0[0], &VD_0[5], Cmp);
98628464483SXinliang David Li ASSERT_EQ(VD_0[0].Value, 0x2000ULL);
98728464483SXinliang David Li ASSERT_EQ(1000U, VD_0[0].Count);
98828464483SXinliang David Li ASSERT_EQ(VD_0[1].Value, 0x3000ULL);
98928464483SXinliang David Li ASSERT_EQ(500U, VD_0[1].Count);
99028464483SXinliang David Li ASSERT_EQ(VD_0[2].Value, 0x1000ULL);
99128464483SXinliang David Li ASSERT_EQ(400U, VD_0[2].Count);
99228464483SXinliang David Li
99328464483SXinliang David Li // callee5 does not have a mapped value -- default to 0.
99428464483SXinliang David Li ASSERT_EQ(VD_0[4].Value, 0ULL);
99528464483SXinliang David Li }
99628464483SXinliang David Li
TEST_P(MaybeSparseInstrProfTest,get_max_function_count)99700dab228SVedant Kumar TEST_P(MaybeSparseInstrProfTest, get_max_function_count) {
99898cce003SDavid Blaikie Writer.addRecord({"foo", 0x1234, {1ULL << 31, 2}}, Err);
99998cce003SDavid Blaikie Writer.addRecord({"bar", 0, {1ULL << 63}}, Err);
100098cce003SDavid Blaikie Writer.addRecord({"baz", 0x5678, {0, 0, 0, 0}}, Err);
10012b6c537bSJustin Bogner auto Profile = Writer.writeBuffer();
10022b6c537bSJustin Bogner readProfile(std::move(Profile));
10032b6c537bSJustin Bogner
1004a6ff69f6SRong Xu ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount(/* IsCS */ false));
10052b6c537bSJustin Bogner }
10062b6c537bSJustin Bogner
TEST_P(MaybeSparseInstrProfTest,get_weighted_function_counts)100700dab228SVedant Kumar TEST_P(MaybeSparseInstrProfTest, get_weighted_function_counts) {
100898cce003SDavid Blaikie Writer.addRecord({"foo", 0x1234, {1, 2}}, 3, Err);
100998cce003SDavid Blaikie Writer.addRecord({"foo", 0x1235, {3, 4}}, 5, Err);
10107f5b47ddSNathan Slingerland auto Profile = Writer.writeBuffer();
10117f5b47ddSNathan Slingerland readProfile(std::move(Profile));
10127f5b47ddSNathan Slingerland
10137f5b47ddSNathan Slingerland std::vector<uint64_t> Counts;
101494b98b2cSDavid Blaikie EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1234, Counts),
101594b98b2cSDavid Blaikie Succeeded());
10167f5b47ddSNathan Slingerland ASSERT_EQ(2U, Counts.size());
10177f5b47ddSNathan Slingerland ASSERT_EQ(3U, Counts[0]);
10187f5b47ddSNathan Slingerland ASSERT_EQ(6U, Counts[1]);
10197f5b47ddSNathan Slingerland
102094b98b2cSDavid Blaikie EXPECT_THAT_ERROR(Reader->getFunctionCounts("foo", 0x1235, Counts),
102194b98b2cSDavid Blaikie Succeeded());
10227f5b47ddSNathan Slingerland ASSERT_EQ(2U, Counts.size());
10237f5b47ddSNathan Slingerland ASSERT_EQ(15U, Counts[0]);
10247f5b47ddSNathan Slingerland ASSERT_EQ(20U, Counts[1]);
10257f5b47ddSNathan Slingerland }
10267f5b47ddSNathan Slingerland
1027a0601e76SXinliang David Li // Testing symtab creator interface used by indexed profile reader.
TEST_P(MaybeSparseInstrProfTest,instr_prof_symtab_test)102800dab228SVedant Kumar TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_test) {
10292ee5c4dbSXinliang David Li std::vector<StringRef> FuncNames;
10302ee5c4dbSXinliang David Li FuncNames.push_back("func1");
10312ee5c4dbSXinliang David Li FuncNames.push_back("func2");
10322ee5c4dbSXinliang David Li FuncNames.push_back("func3");
10332ee5c4dbSXinliang David Li FuncNames.push_back("bar1");
10342ee5c4dbSXinliang David Li FuncNames.push_back("bar2");
10352ee5c4dbSXinliang David Li FuncNames.push_back("bar3");
10362ee5c4dbSXinliang David Li InstrProfSymtab Symtab;
103794b98b2cSDavid Blaikie EXPECT_THAT_ERROR(Symtab.create(FuncNames), Succeeded());
10382ee5c4dbSXinliang David Li StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
10392ee5c4dbSXinliang David Li ASSERT_EQ(StringRef("func1"), R);
10402ee5c4dbSXinliang David Li R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
10412ee5c4dbSXinliang David Li ASSERT_EQ(StringRef("func2"), R);
10422ee5c4dbSXinliang David Li R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
10432ee5c4dbSXinliang David Li ASSERT_EQ(StringRef("func3"), R);
10442ee5c4dbSXinliang David Li R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
10452ee5c4dbSXinliang David Li ASSERT_EQ(StringRef("bar1"), R);
10462ee5c4dbSXinliang David Li R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
10472ee5c4dbSXinliang David Li ASSERT_EQ(StringRef("bar2"), R);
10482ee5c4dbSXinliang David Li R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
10492ee5c4dbSXinliang David Li ASSERT_EQ(StringRef("bar3"), R);
1050c96d3d10SXinliang David Li
105186b4b91eSXinliang David Li // negative tests
105286b4b91eSXinliang David Li R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar4"));
105386b4b91eSXinliang David Li ASSERT_EQ(StringRef(), R);
105486b4b91eSXinliang David Li R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("foo4"));
105586b4b91eSXinliang David Li ASSERT_EQ(StringRef(), R);
105686b4b91eSXinliang David Li
1057c96d3d10SXinliang David Li // Now incrementally update the symtab
105894b98b2cSDavid Blaikie EXPECT_THAT_ERROR(Symtab.addFuncName("blah_1"), Succeeded());
105994b98b2cSDavid Blaikie EXPECT_THAT_ERROR(Symtab.addFuncName("blah_2"), Succeeded());
106094b98b2cSDavid Blaikie EXPECT_THAT_ERROR(Symtab.addFuncName("blah_3"), Succeeded());
1061c96d3d10SXinliang David Li
1062c96d3d10SXinliang David Li // Check again
1063c96d3d10SXinliang David Li R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_1"));
1064c96d3d10SXinliang David Li ASSERT_EQ(StringRef("blah_1"), R);
1065c96d3d10SXinliang David Li R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_2"));
1066c96d3d10SXinliang David Li ASSERT_EQ(StringRef("blah_2"), R);
1067c96d3d10SXinliang David Li R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("blah_3"));
1068c96d3d10SXinliang David Li ASSERT_EQ(StringRef("blah_3"), R);
1069c96d3d10SXinliang David Li R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1"));
1070c96d3d10SXinliang David Li ASSERT_EQ(StringRef("func1"), R);
1071c96d3d10SXinliang David Li R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2"));
1072c96d3d10SXinliang David Li ASSERT_EQ(StringRef("func2"), R);
1073c96d3d10SXinliang David Li R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func3"));
1074c96d3d10SXinliang David Li ASSERT_EQ(StringRef("func3"), R);
1075c96d3d10SXinliang David Li R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar1"));
1076c96d3d10SXinliang David Li ASSERT_EQ(StringRef("bar1"), R);
1077c96d3d10SXinliang David Li R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar2"));
1078c96d3d10SXinliang David Li ASSERT_EQ(StringRef("bar2"), R);
1079c96d3d10SXinliang David Li R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("bar3"));
1080c96d3d10SXinliang David Li ASSERT_EQ(StringRef("bar3"), R);
10812ee5c4dbSXinliang David Li }
10822ee5c4dbSXinliang David Li
1083b5794ca9SVedant Kumar // Test that we get an error when creating a bogus symtab.
TEST_P(MaybeSparseInstrProfTest,instr_prof_bogus_symtab_empty_func_name)1084b5794ca9SVedant Kumar TEST_P(MaybeSparseInstrProfTest, instr_prof_bogus_symtab_empty_func_name) {
1085b5794ca9SVedant Kumar InstrProfSymtab Symtab;
108694b98b2cSDavid Blaikie EXPECT_TRUE(ErrorEquals(instrprof_error::malformed, Symtab.addFuncName("")));
1087b5794ca9SVedant Kumar }
1088b5794ca9SVedant Kumar
1089a0601e76SXinliang David Li // Testing symtab creator interface used by value profile transformer.
TEST_P(MaybeSparseInstrProfTest,instr_prof_symtab_module_test)109000dab228SVedant Kumar TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_module_test) {
109159411db5SXinliang David Li LLVMContext Ctx;
10920eaee545SJonas Devlieghere std::unique_ptr<Module> M = std::make_unique<Module>("MyModule.cpp", Ctx);
109359411db5SXinliang David Li FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
109459411db5SXinliang David Li /*isVarArg=*/false);
109559411db5SXinliang David Li Function::Create(FTy, Function::ExternalLinkage, "Gfoo", M.get());
109659411db5SXinliang David Li Function::Create(FTy, Function::ExternalLinkage, "Gblah", M.get());
109759411db5SXinliang David Li Function::Create(FTy, Function::ExternalLinkage, "Gbar", M.get());
109859411db5SXinliang David Li Function::Create(FTy, Function::InternalLinkage, "Ifoo", M.get());
109959411db5SXinliang David Li Function::Create(FTy, Function::InternalLinkage, "Iblah", M.get());
110059411db5SXinliang David Li Function::Create(FTy, Function::InternalLinkage, "Ibar", M.get());
110159411db5SXinliang David Li Function::Create(FTy, Function::PrivateLinkage, "Pfoo", M.get());
110259411db5SXinliang David Li Function::Create(FTy, Function::PrivateLinkage, "Pblah", M.get());
110359411db5SXinliang David Li Function::Create(FTy, Function::PrivateLinkage, "Pbar", M.get());
110459411db5SXinliang David Li Function::Create(FTy, Function::WeakODRLinkage, "Wfoo", M.get());
110559411db5SXinliang David Li Function::Create(FTy, Function::WeakODRLinkage, "Wblah", M.get());
110659411db5SXinliang David Li Function::Create(FTy, Function::WeakODRLinkage, "Wbar", M.get());
110759411db5SXinliang David Li
110859411db5SXinliang David Li InstrProfSymtab ProfSymtab;
110994b98b2cSDavid Blaikie EXPECT_THAT_ERROR(ProfSymtab.create(*M), Succeeded());
111059411db5SXinliang David Li
111159411db5SXinliang David Li StringRef Funcs[] = {"Gfoo", "Gblah", "Gbar", "Ifoo", "Iblah", "Ibar",
111259411db5SXinliang David Li "Pfoo", "Pblah", "Pbar", "Wfoo", "Wblah", "Wbar"};
111359411db5SXinliang David Li
111459411db5SXinliang David Li for (unsigned I = 0; I < sizeof(Funcs) / sizeof(*Funcs); I++) {
111559411db5SXinliang David Li Function *F = M->getFunction(Funcs[I]);
11166ac3f739SEugene Zelenko ASSERT_TRUE(F != nullptr);
1117da656fe5SXinliang David Li std::string PGOName = getPGOFuncName(*F);
11183865fdc4SXinliang David Li uint64_t Key = IndexedInstrProf::ComputeHash(PGOName);
1119da656fe5SXinliang David Li ASSERT_EQ(StringRef(PGOName),
11203865fdc4SXinliang David Li ProfSymtab.getFuncName(Key));
11213865fdc4SXinliang David Li ASSERT_EQ(StringRef(Funcs[I]), ProfSymtab.getOrigFuncName(Key));
112259411db5SXinliang David Li }
112359411db5SXinliang David Li }
112459411db5SXinliang David Li
1125a0601e76SXinliang David Li // Testing symtab serialization and creator/deserialization interface
1126a0601e76SXinliang David Li // used by coverage map reader, and raw profile reader.
TEST_P(MaybeSparseInstrProfTest,instr_prof_symtab_compression_test)112700dab228SVedant Kumar TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_compression_test) {
1128e413f1a0SXinliang David Li std::vector<std::string> FuncNames1;
1129e413f1a0SXinliang David Li std::vector<std::string> FuncNames2;
1130c2f25cc4SXinliang David Li for (int I = 0; I < 3; I++) {
1131e413f1a0SXinliang David Li std::string str;
1132e413f1a0SXinliang David Li raw_string_ostream OS(str);
1133e413f1a0SXinliang David Li OS << "func_" << I;
1134e413f1a0SXinliang David Li FuncNames1.push_back(OS.str());
1135e413f1a0SXinliang David Li str.clear();
113686705ba5SVedant Kumar OS << "f oooooooooooooo_" << I;
1137e413f1a0SXinliang David Li FuncNames1.push_back(OS.str());
1138e413f1a0SXinliang David Li str.clear();
1139e413f1a0SXinliang David Li OS << "BAR_" << I;
1140e413f1a0SXinliang David Li FuncNames2.push_back(OS.str());
1141e413f1a0SXinliang David Li str.clear();
1142e413f1a0SXinliang David Li OS << "BlahblahBlahblahBar_" << I;
1143e413f1a0SXinliang David Li FuncNames2.push_back(OS.str());
1144e413f1a0SXinliang David Li }
1145e413f1a0SXinliang David Li
1146dd4ae7b5SXinliang David Li for (bool DoCompression : {false, true}) {
1147e413f1a0SXinliang David Li // Compressing:
1148e413f1a0SXinliang David Li std::string FuncNameStrings1;
114994b98b2cSDavid Blaikie EXPECT_THAT_ERROR(collectPGOFuncNameStrings(
1150*ea61750cSCole Kissane FuncNames1,
1151*ea61750cSCole Kissane (DoCompression && compression::zlib::isAvailable()),
115294b98b2cSDavid Blaikie FuncNameStrings1),
115394b98b2cSDavid Blaikie Succeeded());
1154e413f1a0SXinliang David Li
1155e413f1a0SXinliang David Li // Compressing:
1156e413f1a0SXinliang David Li std::string FuncNameStrings2;
115794b98b2cSDavid Blaikie EXPECT_THAT_ERROR(collectPGOFuncNameStrings(
1158*ea61750cSCole Kissane FuncNames2,
1159*ea61750cSCole Kissane (DoCompression && compression::zlib::isAvailable()),
116094b98b2cSDavid Blaikie FuncNameStrings2),
116194b98b2cSDavid Blaikie Succeeded());
1162e413f1a0SXinliang David Li
1163c2f25cc4SXinliang David Li for (int Padding = 0; Padding < 2; Padding++) {
1164e413f1a0SXinliang David Li // Join with paddings :
1165e413f1a0SXinliang David Li std::string FuncNameStrings = FuncNameStrings1;
1166e413f1a0SXinliang David Li for (int P = 0; P < Padding; P++) {
1167e413f1a0SXinliang David Li FuncNameStrings.push_back('\0');
1168e413f1a0SXinliang David Li }
1169e413f1a0SXinliang David Li FuncNameStrings += FuncNameStrings2;
1170e413f1a0SXinliang David Li
11718dec8b1eSXinliang David Li // Now decompress:
1172e413f1a0SXinliang David Li InstrProfSymtab Symtab;
117394b98b2cSDavid Blaikie EXPECT_THAT_ERROR(Symtab.create(StringRef(FuncNameStrings)), Succeeded());
1174e413f1a0SXinliang David Li
11758dec8b1eSXinliang David Li // Now do the checks:
11768dec8b1eSXinliang David Li // First sampling some data points:
1177a8ba7affSXinliang David Li StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[0]));
11788dec8b1eSXinliang David Li ASSERT_EQ(StringRef("func_0"), R);
11798dec8b1eSXinliang David Li R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(FuncNames1[1]));
118086705ba5SVedant Kumar ASSERT_EQ(StringRef("f oooooooooooooo_0"), R);
1181c2f25cc4SXinliang David Li for (int I = 0; I < 3; I++) {
1182e413f1a0SXinliang David Li std::string N[4];
1183e413f1a0SXinliang David Li N[0] = FuncNames1[2 * I];
1184e413f1a0SXinliang David Li N[1] = FuncNames1[2 * I + 1];
1185e413f1a0SXinliang David Li N[2] = FuncNames2[2 * I];
1186e413f1a0SXinliang David Li N[3] = FuncNames2[2 * I + 1];
1187e413f1a0SXinliang David Li for (int J = 0; J < 4; J++) {
1188e413f1a0SXinliang David Li StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash(N[J]));
1189e413f1a0SXinliang David Li ASSERT_EQ(StringRef(N[J]), R);
1190e413f1a0SXinliang David Li }
1191e413f1a0SXinliang David Li }
1192e413f1a0SXinliang David Li }
1193e413f1a0SXinliang David Li }
1194e413f1a0SXinliang David Li }
1195e413f1a0SXinliang David Li
TEST_P(MaybeSparseInstrProfTest,remapping_test)1196ceed4eb1SRichard Smith TEST_P(MaybeSparseInstrProfTest, remapping_test) {
1197ceed4eb1SRichard Smith Writer.addRecord({"_Z3fooi", 0x1234, {1, 2, 3, 4}}, Err);
1198ceed4eb1SRichard Smith Writer.addRecord({"file:_Z3barf", 0x567, {5, 6, 7}}, Err);
1199ceed4eb1SRichard Smith auto Profile = Writer.writeBuffer();
1200ceed4eb1SRichard Smith readProfile(std::move(Profile), llvm::MemoryBuffer::getMemBuffer(R"(
1201ceed4eb1SRichard Smith type i l
1202ceed4eb1SRichard Smith name 3bar 4quux
1203ceed4eb1SRichard Smith )"));
1204ceed4eb1SRichard Smith
1205ceed4eb1SRichard Smith std::vector<uint64_t> Counts;
1206ceed4eb1SRichard Smith for (StringRef FooName : {"_Z3fooi", "_Z3fool"}) {
1207ceed4eb1SRichard Smith EXPECT_THAT_ERROR(Reader->getFunctionCounts(FooName, 0x1234, Counts),
1208ceed4eb1SRichard Smith Succeeded());
1209ceed4eb1SRichard Smith ASSERT_EQ(4u, Counts.size());
1210ceed4eb1SRichard Smith EXPECT_EQ(1u, Counts[0]);
1211ceed4eb1SRichard Smith EXPECT_EQ(2u, Counts[1]);
1212ceed4eb1SRichard Smith EXPECT_EQ(3u, Counts[2]);
1213ceed4eb1SRichard Smith EXPECT_EQ(4u, Counts[3]);
1214ceed4eb1SRichard Smith }
1215ceed4eb1SRichard Smith
1216ceed4eb1SRichard Smith for (StringRef BarName : {"file:_Z3barf", "file:_Z4quuxf"}) {
1217ceed4eb1SRichard Smith EXPECT_THAT_ERROR(Reader->getFunctionCounts(BarName, 0x567, Counts),
1218ceed4eb1SRichard Smith Succeeded());
1219ceed4eb1SRichard Smith ASSERT_EQ(3u, Counts.size());
1220ceed4eb1SRichard Smith EXPECT_EQ(5u, Counts[0]);
1221ceed4eb1SRichard Smith EXPECT_EQ(6u, Counts[1]);
1222ceed4eb1SRichard Smith EXPECT_EQ(7u, Counts[2]);
1223ceed4eb1SRichard Smith }
1224ceed4eb1SRichard Smith
1225ceed4eb1SRichard Smith for (StringRef BadName : {"_Z3foof", "_Z4quuxi", "_Z3barl", "", "_ZZZ",
1226ceed4eb1SRichard Smith "_Z3barf", "otherfile:_Z4quuxf"}) {
1227ceed4eb1SRichard Smith EXPECT_THAT_ERROR(Reader->getFunctionCounts(BadName, 0x1234, Counts),
1228ceed4eb1SRichard Smith Failed());
1229ceed4eb1SRichard Smith EXPECT_THAT_ERROR(Reader->getFunctionCounts(BadName, 0x567, Counts),
1230ceed4eb1SRichard Smith Failed());
1231ceed4eb1SRichard Smith }
1232ceed4eb1SRichard Smith }
1233ceed4eb1SRichard Smith
TEST_F(SparseInstrProfTest,preserve_no_records)123400dab228SVedant Kumar TEST_F(SparseInstrProfTest, preserve_no_records) {
123598cce003SDavid Blaikie Writer.addRecord({"foo", 0x1234, {0}}, Err);
123698cce003SDavid Blaikie Writer.addRecord({"bar", 0x4321, {0, 0}}, Err);
1237910d3d05SVedant Kumar Writer.addRecord({"baz", 0x4321, {0, 0, 0}}, Err);
123800dab228SVedant Kumar
123900dab228SVedant Kumar auto Profile = Writer.writeBuffer();
124000dab228SVedant Kumar readProfile(std::move(Profile));
124100dab228SVedant Kumar
124200dab228SVedant Kumar auto I = Reader->begin(), E = Reader->end();
124300dab228SVedant Kumar ASSERT_TRUE(I == E);
124400dab228SVedant Kumar }
124500dab228SVedant Kumar
1246d4d80a29SBenjamin Kramer INSTANTIATE_TEST_SUITE_P(MaybeSparse, MaybeSparseInstrProfTest,
1247d4d80a29SBenjamin Kramer ::testing::Bool());
124800dab228SVedant Kumar
1249d6c15b66SVedant Kumar #if defined(_LP64) && defined(EXPENSIVE_CHECKS)
TEST(ProfileReaderTest,ReadsLargeFiles)1250d6c15b66SVedant Kumar TEST(ProfileReaderTest, ReadsLargeFiles) {
1251d6c15b66SVedant Kumar const size_t LargeSize = 1ULL << 32; // 4GB
1252d6c15b66SVedant Kumar
1253d6c15b66SVedant Kumar auto RawProfile = WritableMemoryBuffer::getNewUninitMemBuffer(LargeSize);
1254d6c15b66SVedant Kumar if (!RawProfile)
1255d6c15b66SVedant Kumar return;
1256d6c15b66SVedant Kumar auto RawProfileReaderOrErr = InstrProfReader::create(std::move(RawProfile));
1257d6c15b66SVedant Kumar ASSERT_TRUE(InstrProfError::take(RawProfileReaderOrErr.takeError()) ==
1258d6c15b66SVedant Kumar instrprof_error::unrecognized_format);
1259d6c15b66SVedant Kumar
1260d6c15b66SVedant Kumar auto IndexedProfile = WritableMemoryBuffer::getNewUninitMemBuffer(LargeSize);
1261d6c15b66SVedant Kumar if (!IndexedProfile)
1262d6c15b66SVedant Kumar return;
1263d6c15b66SVedant Kumar auto IndexedReaderOrErr =
1264d6c15b66SVedant Kumar IndexedInstrProfReader::create(std::move(IndexedProfile), nullptr);
1265d6c15b66SVedant Kumar ASSERT_TRUE(InstrProfError::take(IndexedReaderOrErr.takeError()) ==
1266d6c15b66SVedant Kumar instrprof_error::bad_magic);
1267d6c15b66SVedant Kumar }
1268d6c15b66SVedant Kumar #endif
1269d6c15b66SVedant Kumar
12702b6c537bSJustin Bogner } // end anonymous namespace
1271