diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/IR/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/lib/IR/ProfileSummary.cpp (renamed from llvm/lib/ProfileData/ProfileSummary.cpp) | 119 | ||||
-rw-r--r-- | llvm/lib/ProfileData/CMakeLists.txt | 2 | ||||
-rw-r--r-- | llvm/lib/ProfileData/InstrProfReader.cpp | 22 | ||||
-rw-r--r-- | llvm/lib/ProfileData/InstrProfWriter.cpp | 15 | ||||
-rw-r--r-- | llvm/lib/ProfileData/ProfileSummaryBuilder.cpp | 113 | ||||
-rw-r--r-- | llvm/lib/ProfileData/SampleProfReader.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/ProfileData/SampleProfWriter.cpp | 6 |
8 files changed, 151 insertions, 133 deletions
diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt index f3f87338ca4..07cec97084e 100644 --- a/llvm/lib/IR/CMakeLists.txt +++ b/llvm/lib/IR/CMakeLists.txt @@ -43,6 +43,7 @@ add_llvm_library(LLVMCore Pass.cpp PassManager.cpp PassRegistry.cpp + ProfileSummary.cpp Statepoint.cpp Type.cpp TypeFinder.cpp diff --git a/llvm/lib/ProfileData/ProfileSummary.cpp b/llvm/lib/IR/ProfileSummary.cpp index dfe44e32bbe..51bcd1845c7 100644 --- a/llvm/lib/ProfileData/ProfileSummary.cpp +++ b/llvm/lib/IR/ProfileSummary.cpp @@ -1,4 +1,4 @@ -//=-- Profilesummary.cpp - Profile summary computation ----------------------=// +//=-- Profilesummary.cpp - Profile summary support --------------------------=// // // The LLVM Compiler Infrastructure // @@ -7,134 +7,23 @@ // //===----------------------------------------------------------------------===// // -// This file contains support for computing profile summary data. +// This file contains support for converting profile summary data from/to +// metadata. // //===----------------------------------------------------------------------===// +#include "llvm/IR/ProfileSummary.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Type.h" -#include "llvm/ProfileData/InstrProf.h" -#include "llvm/ProfileData/ProfileCommon.h" -#include "llvm/ProfileData/SampleProf.h" #include "llvm/Support/Casting.h" using namespace llvm; -// A set of cutoff values. Each value, when divided by ProfileSummary::Scale -// (which is 1000000) is a desired percentile of total counts. -const std::vector<uint32_t> ProfileSummary::DefaultCutoffs( - {10000, /* 1% */ - 100000, /* 10% */ - 200000, 300000, 400000, 500000, 600000, 500000, 600000, 700000, 800000, - 900000, 950000, 990000, 999000, 999900, 999990, 999999}); const char *ProfileSummary::KindStr[2] = {"InstrProf", "SampleProfile"}; -void InstrProfSummary::addRecord(const InstrProfRecord &R) { - // The first counter is not necessarily an entry count for IR - // instrumentation profiles. - // Eventually MaxFunctionCount will become obsolete and this can be - // removed. - addEntryCount(R.Counts[0]); - for (size_t I = 1, E = R.Counts.size(); I < E; ++I) - addInternalCount(R.Counts[I]); -} - -// To compute the detailed summary, we consider each line containing samples as -// equivalent to a block with a count in the instrumented profile. -void SampleProfileSummary::addRecord(const sampleprof::FunctionSamples &FS) { - NumFunctions++; - if (FS.getHeadSamples() > MaxFunctionCount) - MaxFunctionCount = FS.getHeadSamples(); - for (const auto &I : FS.getBodySamples()) - addCount(I.second.getSamples()); -} - -// The argument to this method is a vector of cutoff percentages and the return -// value is a vector of (Cutoff, MinCount, NumCounts) triplets. -void ProfileSummary::computeDetailedSummary() { - if (DetailedSummaryCutoffs.empty()) - return; - auto Iter = CountFrequencies.begin(); - auto End = CountFrequencies.end(); - std::sort(DetailedSummaryCutoffs.begin(), DetailedSummaryCutoffs.end()); - - uint32_t CountsSeen = 0; - uint64_t CurrSum = 0, Count = 0; - - for (uint32_t Cutoff : DetailedSummaryCutoffs) { - assert(Cutoff <= 999999); - APInt Temp(128, TotalCount); - APInt N(128, Cutoff); - APInt D(128, ProfileSummary::Scale); - Temp *= N; - Temp = Temp.sdiv(D); - uint64_t DesiredCount = Temp.getZExtValue(); - assert(DesiredCount <= TotalCount); - while (CurrSum < DesiredCount && Iter != End) { - Count = Iter->first; - uint32_t Freq = Iter->second; - CurrSum += (Count * Freq); - CountsSeen += Freq; - Iter++; - } - assert(CurrSum >= DesiredCount); - ProfileSummaryEntry PSE = {Cutoff, Count, CountsSeen}; - DetailedSummary.push_back(PSE); - } -} - -// Returns true if the function is a hot function. -bool ProfileSummary::isFunctionHot(const Function *F) { - // FIXME: update when summary data is stored in module's metadata. - return false; -} - -// Returns true if the function is a cold function. -bool ProfileSummary::isFunctionUnlikely(const Function *F) { - if (F->hasFnAttribute(Attribute::Cold)) { - return true; - } - if (!F->getEntryCount()) { - return false; - } - // FIXME: update when summary data is stored in module's metadata. - return (*F->getEntryCount()) == 0; -} - -InstrProfSummary::InstrProfSummary(const IndexedInstrProf::Summary &S) - : ProfileSummary(PSK_Instr), - MaxInternalBlockCount( - S.get(IndexedInstrProf::Summary::MaxInternalBlockCount)) { - - TotalCount = S.get(IndexedInstrProf::Summary::TotalBlockCount); - MaxCount = S.get(IndexedInstrProf::Summary::MaxBlockCount); - MaxFunctionCount = S.get(IndexedInstrProf::Summary::MaxFunctionCount); - NumCounts = S.get(IndexedInstrProf::Summary::TotalNumBlocks); - NumFunctions = S.get(IndexedInstrProf::Summary::TotalNumFunctions); - - for (unsigned I = 0; I < S.NumCutoffEntries; I++) { - const IndexedInstrProf::Summary::Entry &Ent = S.getEntry(I); - DetailedSummary.emplace_back((uint32_t)Ent.Cutoff, Ent.MinBlockCount, - Ent.NumBlocks); - } -} - -void InstrProfSummary::addEntryCount(uint64_t Count) { - addCount(Count); - NumFunctions++; - if (Count > MaxFunctionCount) - MaxFunctionCount = Count; -} - -void InstrProfSummary::addInternalCount(uint64_t Count) { - addCount(Count); - if (Count > MaxInternalBlockCount) - MaxInternalBlockCount = Count; -} - // Return an MDTuple with two elements. The first element is a string Key and // the second is a uint64_t Value. static Metadata *getKeyValMD(LLVMContext &Context, const char *Key, diff --git a/llvm/lib/ProfileData/CMakeLists.txt b/llvm/lib/ProfileData/CMakeLists.txt index e68717c8188..cd65762ae6a 100644 --- a/llvm/lib/ProfileData/CMakeLists.txt +++ b/llvm/lib/ProfileData/CMakeLists.txt @@ -2,7 +2,7 @@ add_llvm_library(LLVMProfileData InstrProf.cpp InstrProfReader.cpp InstrProfWriter.cpp - ProfileSummary.cpp + ProfileSummaryBuilder.cpp SampleProf.cpp SampleProfReader.cpp SampleProfWriter.cpp diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp index 2678ac28561..33535fd8eb6 100644 --- a/llvm/lib/ProfileData/InstrProfReader.cpp +++ b/llvm/lib/ProfileData/InstrProfReader.cpp @@ -576,6 +576,7 @@ bool IndexedInstrProfReader::hasFormat(const MemoryBuffer &DataBuffer) { const unsigned char * IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version, const unsigned char *Cur) { + using namespace IndexedInstrProf; using namespace support; if (Version >= IndexedInstrProf::Version4) { const IndexedInstrProf::Summary *SummaryInLE = @@ -594,15 +595,28 @@ IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version, for (unsigned I = 0; I < SummarySize / sizeof(uint64_t); I++) Dst[I] = endian::byte_swap<uint64_t, little>(Src[I]); + llvm::SummaryEntryVector DetailedSummary; + for (unsigned I = 0; I < SummaryData->NumCutoffEntries; I++) { + const IndexedInstrProf::Summary::Entry &Ent = SummaryData->getEntry(I); + DetailedSummary.emplace_back((uint32_t)Ent.Cutoff, Ent.MinBlockCount, + Ent.NumBlocks); + } // initialize InstrProfSummary using the SummaryData from disk. - this->Summary = llvm::make_unique<InstrProfSummary>(*(SummaryData.get())); + this->Summary = llvm::make_unique<InstrProfSummary>( + SummaryData->get(Summary::TotalBlockCount), + SummaryData->get(Summary::MaxBlockCount), + SummaryData->get(Summary::MaxInternalBlockCount), + SummaryData->get(Summary::MaxFunctionCount), + SummaryData->get(Summary::TotalNumBlocks), + SummaryData->get(Summary::TotalNumFunctions), DetailedSummary); return Cur + SummarySize; } else { // For older version of profile data, we need to compute on the fly: using namespace IndexedInstrProf; - this->Summary = - llvm::make_unique<InstrProfSummary>(ProfileSummary::DefaultCutoffs); - this->Summary->computeDetailedSummary(); + InstrProfSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs); + // FIXME: This only computes an empty summary. Need to call addRecord for + // all InstrProfRecords to get the correct summary. + this->Summary.reset(Builder.getSummary()); return Cur; } } diff --git a/llvm/lib/ProfileData/InstrProfWriter.cpp b/llvm/lib/ProfileData/InstrProfWriter.cpp index 9b01dac313b..1036a10ed8a 100644 --- a/llvm/lib/ProfileData/InstrProfWriter.cpp +++ b/llvm/lib/ProfileData/InstrProfWriter.cpp @@ -84,7 +84,7 @@ public: typedef uint64_t offset_type; support::endianness ValueProfDataEndianness; - InstrProfSummary *TheProfileSummary; + InstrProfSummaryBuilder *SummaryBuilder; InstrProfRecordWriterTrait() : ValueProfDataEndianness(support::little) {} static hash_value_type ComputeHash(key_type_ref K) { @@ -123,7 +123,7 @@ public: endian::Writer<little> LE(Out); for (const auto &ProfileData : *V) { const InstrProfRecord &ProfRecord = ProfileData.second; - TheProfileSummary->addRecord(ProfRecord); + SummaryBuilder->addRecord(ProfRecord); LE.write<uint64_t>(ProfileData.first); // Function hash LE.write<uint64_t>(ProfRecord.Counts.size()); @@ -215,8 +215,8 @@ void InstrProfWriter::writeImpl(ProfOStream &OS) { OnDiskChainedHashTableGenerator<InstrProfRecordWriterTrait> Generator; using namespace IndexedInstrProf; - InstrProfSummary PS(ProfileSummary::DefaultCutoffs); - InfoObj->TheProfileSummary = &PS; + InstrProfSummaryBuilder ISB(ProfileSummaryBuilder::DefaultCutoffs); + InfoObj->SummaryBuilder = &ISB; // Populate the hash table generator. for (const auto &I : FunctionData) @@ -245,7 +245,7 @@ void InstrProfWriter::writeImpl(ProfOStream &OS) { OS.write(0); // Reserve space to write profile summary data. - uint32_t NumEntries = ProfileSummary::DefaultCutoffs.size(); + uint32_t NumEntries = ProfileSummaryBuilder::DefaultCutoffs.size(); uint32_t SummarySize = Summary::getSize(Summary::NumKinds, NumEntries); // Remember the summary offset. uint64_t SummaryOffset = OS.tell(); @@ -260,8 +260,9 @@ void InstrProfWriter::writeImpl(ProfOStream &OS) { IndexedInstrProf::allocSummary(SummarySize); // Compute the Summary and copy the data to the data // structure to be serialized out (to disk or buffer). - setSummary(TheSummary.get(), PS); - InfoObj->TheProfileSummary = 0; + InstrProfSummary *IPS = ISB.getSummary(); + setSummary(TheSummary.get(), *IPS); + InfoObj->SummaryBuilder = 0; // Now do the final patch: PatchItem PatchItems[] = { diff --git a/llvm/lib/ProfileData/ProfileSummaryBuilder.cpp b/llvm/lib/ProfileData/ProfileSummaryBuilder.cpp new file mode 100644 index 00000000000..3d32722ab63 --- /dev/null +++ b/llvm/lib/ProfileData/ProfileSummaryBuilder.cpp @@ -0,0 +1,113 @@ +//=-- ProfilesummaryBuilder.cpp - Profile summary computation ---------------=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains support for computing profile summary data. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/Attributes.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Metadata.h" +#include "llvm/IR/Type.h" +#include "llvm/ProfileData/InstrProf.h" +#include "llvm/ProfileData/ProfileCommon.h" +#include "llvm/ProfileData/SampleProf.h" +#include "llvm/Support/Casting.h" + +using namespace llvm; + +// A set of cutoff values. Each value, when divided by ProfileSummary::Scale +// (which is 1000000) is a desired percentile of total counts. +const std::vector<uint32_t> ProfileSummaryBuilder::DefaultCutoffs( + {10000, /* 1% */ + 100000, /* 10% */ + 200000, 300000, 400000, 500000, 600000, 500000, 600000, 700000, 800000, + 900000, 950000, 990000, 999000, 999900, 999990, 999999}); + +void InstrProfSummaryBuilder::addRecord(const InstrProfRecord &R) { + // The first counter is not necessarily an entry count for IR + // instrumentation profiles. + // Eventually MaxFunctionCount will become obsolete and this can be + // removed. + addEntryCount(R.Counts[0]); + for (size_t I = 1, E = R.Counts.size(); I < E; ++I) + addInternalCount(R.Counts[I]); +} + +// To compute the detailed summary, we consider each line containing samples as +// equivalent to a block with a count in the instrumented profile. +void SampleProfileSummaryBuilder::addRecord( + const sampleprof::FunctionSamples &FS) { + NumFunctions++; + if (FS.getHeadSamples() > MaxFunctionCount) + MaxFunctionCount = FS.getHeadSamples(); + for (const auto &I : FS.getBodySamples()) + addCount(I.second.getSamples()); +} + +// The argument to this method is a vector of cutoff percentages and the return +// value is a vector of (Cutoff, MinCount, NumCounts) triplets. +void ProfileSummaryBuilder::computeDetailedSummary() { + if (DetailedSummaryCutoffs.empty()) + return; + auto Iter = CountFrequencies.begin(); + auto End = CountFrequencies.end(); + std::sort(DetailedSummaryCutoffs.begin(), DetailedSummaryCutoffs.end()); + + uint32_t CountsSeen = 0; + uint64_t CurrSum = 0, Count = 0; + + for (uint32_t Cutoff : DetailedSummaryCutoffs) { + assert(Cutoff <= 999999); + APInt Temp(128, TotalCount); + APInt N(128, Cutoff); + APInt D(128, ProfileSummary::Scale); + Temp *= N; + Temp = Temp.sdiv(D); + uint64_t DesiredCount = Temp.getZExtValue(); + assert(DesiredCount <= TotalCount); + while (CurrSum < DesiredCount && Iter != End) { + Count = Iter->first; + uint32_t Freq = Iter->second; + CurrSum += (Count * Freq); + CountsSeen += Freq; + Iter++; + } + assert(CurrSum >= DesiredCount); + ProfileSummaryEntry PSE = {Cutoff, Count, CountsSeen}; + DetailedSummary.push_back(PSE); + } +} + +SampleProfileSummary *SampleProfileSummaryBuilder::getSummary() { + computeDetailedSummary(); + return new SampleProfileSummary(TotalCount, MaxCount, MaxFunctionCount, + NumCounts, NumFunctions, DetailedSummary); +} + +InstrProfSummary *InstrProfSummaryBuilder::getSummary() { + computeDetailedSummary(); + return new InstrProfSummary(TotalCount, MaxCount, MaxInternalBlockCount, + MaxFunctionCount, NumCounts, NumFunctions, + DetailedSummary); +} + +void InstrProfSummaryBuilder::addEntryCount(uint64_t Count) { + addCount(Count); + NumFunctions++; + if (Count > MaxFunctionCount) + MaxFunctionCount = Count; +} + +void InstrProfSummaryBuilder::addInternalCount(uint64_t Count) { + addCount(Count); + if (Count > MaxInternalBlockCount) + MaxInternalBlockCount = Count; +} diff --git a/llvm/lib/ProfileData/SampleProfReader.cpp b/llvm/lib/ProfileData/SampleProfReader.cpp index 63f828697d6..14023bbd509 100644 --- a/llvm/lib/ProfileData/SampleProfReader.cpp +++ b/llvm/lib/ProfileData/SampleProfReader.cpp @@ -793,10 +793,10 @@ SampleProfileReader::create(std::unique_ptr<MemoryBuffer> &B, LLVMContext &C) { // For text and GCC file formats, we compute the summary after reading the // profile. Binary format has the profile summary in its header. void SampleProfileReader::computeSummary() { - Summary.reset(new SampleProfileSummary(ProfileSummary::DefaultCutoffs)); + SampleProfileSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs); for (const auto &I : Profiles) { const FunctionSamples &Profile = I.second; - Summary->addRecord(Profile); + Builder.addRecord(Profile); } - Summary->computeDetailedSummary(); + Summary.reset(Builder.getSummary()); } diff --git a/llvm/lib/ProfileData/SampleProfWriter.cpp b/llvm/lib/ProfileData/SampleProfWriter.cpp index 2f6490224c5..56e836c69cd 100644 --- a/llvm/lib/ProfileData/SampleProfWriter.cpp +++ b/llvm/lib/ProfileData/SampleProfWriter.cpp @@ -255,10 +255,10 @@ SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS, void SampleProfileWriter::computeSummary( const StringMap<FunctionSamples> &ProfileMap) { - Summary.reset(new SampleProfileSummary(ProfileSummary::DefaultCutoffs)); + SampleProfileSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs); for (const auto &I : ProfileMap) { const FunctionSamples &Profile = I.second; - Summary->addRecord(Profile); + Builder.addRecord(Profile); } - Summary->computeDetailedSummary(); + Summary.reset(Builder.getSummary()); } |