diff options
author | Xinliang David Li <davidxl@google.com> | 2016-01-08 03:49:59 +0000 |
---|---|---|
committer | Xinliang David Li <davidxl@google.com> | 2016-01-08 03:49:59 +0000 |
commit | 51dc04cff25c5f9ab97dfa88fdd81566302fd349 (patch) | |
tree | 9df0beb2024c9f6ea7d69ea44a152797045d7869 /llvm/unittests/ProfileData/InstrProfTest.cpp | |
parent | 652b97bcf7eb2c7d0ac118401581ff131051b65d (diff) | |
download | bcm5719-llvm-51dc04cff25c5f9ab97dfa88fdd81566302fd349.tar.gz bcm5719-llvm-51dc04cff25c5f9ab97dfa88fdd81566302fd349.zip |
[PGO] Fix a bug in InstProfWriter addRecord
For a new record with weight != 1, only edge profiling
counters are scaled, VP data is not properly scaled.
This patch refactors the code and fixes the problem.
Also added sort by count interface (for follow up patch).
llvm-svn: 257143
Diffstat (limited to 'llvm/unittests/ProfileData/InstrProfTest.cpp')
-rw-r--r-- | llvm/unittests/ProfileData/InstrProfTest.cpp | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/llvm/unittests/ProfileData/InstrProfTest.cpp b/llvm/unittests/ProfileData/InstrProfTest.cpp index 1ccc3ca5d69..a4fadd3d65d 100644 --- a/llvm/unittests/ProfileData/InstrProfTest.cpp +++ b/llvm/unittests/ProfileData/InstrProfTest.cpp @@ -164,6 +164,62 @@ TEST_F(InstrProfTest, get_icall_data_read_write) { [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) { return VD1.Count > VD2.Count; }); + + ASSERT_EQ(3U, VD[0].Count); + ASSERT_EQ(2U, VD[1].Count); + ASSERT_EQ(1U, VD[2].Count); + + ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3")); + ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2")); + ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1")); +} + +TEST_F(InstrProfTest, get_icall_data_read_write_with_weight) { + InstrProfRecord Record1("caller", 0x1234, {1, 2}); + InstrProfRecord Record2("callee1", 0x1235, {3, 4}); + InstrProfRecord Record3("callee2", 0x1235, {3, 4}); + InstrProfRecord Record4("callee3", 0x1235, {3, 4}); + + // 4 value sites. + Record1.reserveSites(IPVK_IndirectCallTarget, 4); + InstrProfValueData VD0[] = {{(uint64_t) "callee1", 1}, + {(uint64_t) "callee2", 2}, + {(uint64_t) "callee3", 3}}; + Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr); + // No value profile data at the second site. + Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr); + InstrProfValueData VD2[] = {{(uint64_t) "callee1", 1}, + {(uint64_t) "callee2", 2}}; + Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr); + InstrProfValueData VD3[] = {{(uint64_t) "callee1", 1}}; + Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr); + + Writer.addRecord(std::move(Record1), 10); + Writer.addRecord(std::move(Record2)); + Writer.addRecord(std::move(Record3)); + Writer.addRecord(std::move(Record4)); + auto Profile = Writer.writeBuffer(); + readProfile(std::move(Profile)); + + ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234); + ASSERT_TRUE(NoError(R.getError())); + ASSERT_EQ(4U, R.get().getNumValueSites(IPVK_IndirectCallTarget)); + ASSERT_EQ(3U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); + ASSERT_EQ(0U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 1)); + ASSERT_EQ(2U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 2)); + ASSERT_EQ(1U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 3)); + + std::unique_ptr<InstrProfValueData[]> VD = + R.get().getValueForSite(IPVK_IndirectCallTarget, 0); + // Now sort the target acording to frequency. + std::sort(&VD[0], &VD[3], + [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) { + return VD1.Count > VD2.Count; + }); + ASSERT_EQ(30U, VD[0].Count); + ASSERT_EQ(20U, VD[1].Count); + ASSERT_EQ(10U, VD[2].Count); + ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3")); ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2")); ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1")); |