From 8d1c983f451f9256062bd92ba8358723c7254216 Mon Sep 17 00:00:00 2001 From: Dehao Chen Date: Thu, 11 May 2017 23:43:44 +0000 Subject: [PATCH] Change sample profile writer to make it deterministic. Summary: This patch changes the function profile output order to be deterministic. In order to make it easier to understand, hottest functions (with most total samples) is ordered first. Reviewers: dnovillo, davidxl Reviewed By: dnovillo Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D33111 llvm-svn: 302851 --- .../llvm/ProfileData/SampleProfWriter.h | 11 +---- llvm/lib/ProfileData/SampleProfWriter.cpp | 42 +++++++++++++++++-- .../llvm-profdata/sample-profile-basic.test | 7 ++-- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/llvm/include/llvm/ProfileData/SampleProfWriter.h b/llvm/include/llvm/ProfileData/SampleProfWriter.h index 9d69af32dd46..86af1038d74e 100644 --- a/llvm/include/llvm/ProfileData/SampleProfWriter.h +++ b/llvm/include/llvm/ProfileData/SampleProfWriter.h @@ -43,16 +43,7 @@ public: /// Write all the sample profiles in the given map of samples. /// /// \returns status code of the file update operation. - std::error_code write(const StringMap &ProfileMap) { - if (std::error_code EC = writeHeader(ProfileMap)) - return EC; - for (const auto &I : ProfileMap) { - const FunctionSamples &Profile = I.second; - if (std::error_code EC = write(Profile)) - return EC; - } - return sampleprof_error::success; - } + std::error_code write(const StringMap &ProfileMap); raw_ostream &getOutputStream() { return *OutputStream; } diff --git a/llvm/lib/ProfileData/SampleProfWriter.cpp b/llvm/lib/ProfileData/SampleProfWriter.cpp index b91b6fb7c7ad..b05efa7417b9 100644 --- a/llvm/lib/ProfileData/SampleProfWriter.cpp +++ b/llvm/lib/ProfileData/SampleProfWriter.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,32 @@ using namespace llvm; using namespace sampleprof; +std::error_code +SampleProfileWriter::write(const StringMap &ProfileMap) { + if (std::error_code EC = writeHeader(ProfileMap)) + return EC; + + // Sort the ProfileMap by total samples. + typedef std::pair NameFunctionSamples; + std::vector V; + for (const auto &I : ProfileMap) + V.push_back(std::make_pair(I.getKey(), &I.second)); + + std::stable_sort( + V.begin(), V.end(), + [](const NameFunctionSamples &A, const NameFunctionSamples &B) { + if (A.second->getTotalSamples() == B.second->getTotalSamples()) + return A.first > B.first; + return A.second->getTotalSamples() > B.second->getTotalSamples(); + }); + + for (const auto &I : V) { + if (std::error_code EC = write(*I.second)) + return EC; + } + return sampleprof_error::success; +} + /// \brief Write samples to a text file. /// /// Note: it may be tempting to implement this in terms of @@ -97,8 +124,7 @@ std::error_code SampleProfileWriterBinary::writeNameIdx(StringRef FName) { } void SampleProfileWriterBinary::addName(StringRef FName) { - auto NextIdx = NameTable.size(); - NameTable.insert(std::make_pair(FName, NextIdx)); + NameTable.insert(std::make_pair(FName, 0)); } void SampleProfileWriterBinary::addNames(const FunctionSamples &S) { @@ -136,10 +162,18 @@ std::error_code SampleProfileWriterBinary::writeHeader( addNames(I.second); } + // Sort the names to make NameTable is deterministic. + std::set V; + for (const auto &I : NameTable) + V.insert(I.first); + int i = 0; + for (const StringRef &N : V) + NameTable[N] = i++; + // Write out the name table. encodeULEB128(NameTable.size(), OS); - for (auto N : NameTable) { - OS << N.first; + for (auto N : V) { + OS << N; encodeULEB128(0, OS); } return sampleprof_error::success; diff --git a/llvm/test/tools/llvm-profdata/sample-profile-basic.test b/llvm/test/tools/llvm-profdata/sample-profile-basic.test index 211d8c5bbd84..3ba42c20f2e8 100644 --- a/llvm/test/tools/llvm-profdata/sample-profile-basic.test +++ b/llvm/test/tools/llvm-profdata/sample-profile-basic.test @@ -25,9 +25,10 @@ RUN: diff %t-binary %t-text counters have doubled. RUN: llvm-profdata merge --sample %p/Inputs/sample-profile.proftext -o %t-binprof RUN: llvm-profdata merge --sample --text %p/Inputs/sample-profile.proftext %t-binprof -o - | FileCheck %s --check-prefix=MERGE1 -MERGE1-DAG: main:368038:0 -MERGE1-DAG: 9: 4128 _Z3fooi:1262 _Z3bari:2942 -MERGE1-DAG: _Z3fooi:15422:1220 +MERGE1: main:368038:0 +MERGE1: 9: 4128 _Z3fooi:1262 _Z3bari:2942 +MERGE1: _Z3bari:40602:2874 +MERGE1: _Z3fooi:15422:1220 5- Detect invalid text encoding (e.g. instrumentation profile text format). RUN: not llvm-profdata show --sample %p/Inputs/foo3bar3-1.proftext 2>&1 | FileCheck %s --check-prefix=BADTEXT