summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/IR/CMakeLists.txt1
-rw-r--r--llvm/lib/IR/ProfileSummary.cpp (renamed from llvm/lib/ProfileData/ProfileSummary.cpp)119
-rw-r--r--llvm/lib/ProfileData/CMakeLists.txt2
-rw-r--r--llvm/lib/ProfileData/InstrProfReader.cpp22
-rw-r--r--llvm/lib/ProfileData/InstrProfWriter.cpp15
-rw-r--r--llvm/lib/ProfileData/ProfileSummaryBuilder.cpp113
-rw-r--r--llvm/lib/ProfileData/SampleProfReader.cpp6
-rw-r--r--llvm/lib/ProfileData/SampleProfWriter.cpp6
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());
}
OpenPOWER on IntegriCloud