Skip to content

Commit

Permalink
[PGO] Context sensitive PGO (part 2)
Browse files Browse the repository at this point in the history
Part 2 of CSPGO changes (mostly related to ProfileSummary).
Note that I use a default parameter in setProfileSummary() and getSummary().
This is to break the dependency in clang. I will make the parameter explicit
after changing clang in a separated patch.

Differential Revision: https://reviews.llvm.org/D54175


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355131 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
xur-llvm committed Feb 28, 2019
1 parent 014b2ad commit 5af7fe3
Show file tree
Hide file tree
Showing 17 changed files with 182 additions and 47 deletions.
4 changes: 4 additions & 0 deletions docs/CommandGuide/llvm-profdata.rst
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ OPTIONS
Only output names of functions whose max count value are below the cutoff
value.

.. option:: -showcs
Only show context sensitive profile counts. The default is to filter all
context sensitive profile counts.

EXIT STATUS
-----------

Expand Down
6 changes: 6 additions & 0 deletions include/llvm/Analysis/ProfileSummaryInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ class ProfileSummaryInfo {
Summary->getKind() == ProfileSummary::PSK_Instr;
}

/// Returns true if module \c M has context sensitive instrumentation profile.
bool hasCSInstrumentationProfile() {
return hasProfileSummary() &&
Summary->getKind() == ProfileSummary::PSK_CSInstr;
}

/// Handle the invalidation of this information.
///
/// When used as a result of \c ProfileSummaryAnalysis this method will be
Expand Down
10 changes: 7 additions & 3 deletions include/llvm/IR/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "llvm/IR/GlobalIFunc.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/ProfileSummary.h"
#include "llvm/IR/SymbolTableListTraits.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/CodeGen.h"
Expand Down Expand Up @@ -868,10 +869,13 @@ class Module {
/// @{

/// Attach profile summary metadata to this module.
void setProfileSummary(Metadata *M);
// TODO: Remove the default paramter.
void setProfileSummary(Metadata *M,
ProfileSummary::Kind Kind = ProfileSummary::PSK_Instr);

/// Returns profile summary metadata
Metadata *getProfileSummary();
/// Returns profile summary metadata. When IsCS is true, use the context
/// sensitive profile summary.
Metadata *getProfileSummary(bool IsCS);
/// @}

/// Returns true if PLT should be avoided for RTLib calls.
Expand Down
3 changes: 1 addition & 2 deletions include/llvm/IR/ProfileSummary.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,10 @@ using SummaryEntryVector = std::vector<ProfileSummaryEntry>;

class ProfileSummary {
public:
enum Kind { PSK_Instr, PSK_Sample };
enum Kind { PSK_Instr, PSK_CSInstr, PSK_Sample };

private:
const Kind PSK;
static const char *KindStr[2];
SummaryEntryVector DetailedSummary;
uint64_t TotalCount, MaxCount, MaxInternalCount, MaxFunctionCount;
uint32_t NumCounts, NumFunctions;
Expand Down
47 changes: 44 additions & 3 deletions include/llvm/ProfileData/InstrProfReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ class InstrProfReader {

virtual bool isIRLevelProfile() const = 0;

virtual bool hasCSIRLevelProfile() const = 0;

/// Return the PGO symtab. There are three different readers:
/// Raw, Text, and Indexed profile readers. The first two types
/// of readers are used only by llvm-profdata tool, while the indexed
Expand Down Expand Up @@ -142,6 +144,7 @@ class TextInstrProfReader : public InstrProfReader {
/// Iterator over the profile data.
line_iterator Line;
bool IsIRLevelProfile = false;
bool HasCSIRLevelProfile = false;

Error readValueProfileData(InstrProfRecord &Record);

Expand All @@ -156,6 +159,8 @@ class TextInstrProfReader : public InstrProfReader {

bool isIRLevelProfile() const override { return IsIRLevelProfile; }

bool hasCSIRLevelProfile() const override { return HasCSIRLevelProfile; }

/// Read the header.
Error readHeader() override;

Expand Down Expand Up @@ -212,6 +217,10 @@ class RawInstrProfReader : public InstrProfReader {
return (Version & VARIANT_MASK_IR_PROF) != 0;
}

bool hasCSIRLevelProfile() const override {
return (Version & VARIANT_MASK_CSIR_PROF) != 0;
}

InstrProfSymtab &getSymtab() override {
assert(Symtab.get());
return *Symtab.get();
Expand Down Expand Up @@ -341,6 +350,7 @@ struct InstrProfReaderIndexBase {
virtual void setValueProfDataEndianness(support::endianness Endianness) = 0;
virtual uint64_t getVersion() const = 0;
virtual bool isIRLevelProfile() const = 0;
virtual bool hasCSIRLevelProfile() const = 0;
virtual Error populateSymtab(InstrProfSymtab &) = 0;
};

Expand Down Expand Up @@ -385,6 +395,10 @@ class InstrProfReaderIndex : public InstrProfReaderIndexBase {
return (FormatVersion & VARIANT_MASK_IR_PROF) != 0;
}

bool hasCSIRLevelProfile() const override {
return (FormatVersion & VARIANT_MASK_CSIR_PROF) != 0;
}

Error populateSymtab(InstrProfSymtab &Symtab) override {
return Symtab.create(HashTable->keys());
}
Expand Down Expand Up @@ -412,13 +426,16 @@ class IndexedInstrProfReader : public InstrProfReader {
std::unique_ptr<InstrProfReaderRemapper> Remapper;
/// Profile summary data.
std::unique_ptr<ProfileSummary> Summary;
/// Context sensitive profile summary data.
std::unique_ptr<ProfileSummary> CS_Summary;
// Index to the current record in the record array.
unsigned RecordIndex;

// Read the profile summary. Return a pointer pointing to one byte past the
// end of the summary data if it exists or the input \c Cur.
// \c UseCS indicates whether to use the context-sensitive profile summary.
const unsigned char *readSummary(IndexedInstrProf::ProfVersion Version,
const unsigned char *Cur);
const unsigned char *Cur, bool UseCS);

public:
IndexedInstrProfReader(
Expand All @@ -432,6 +449,9 @@ class IndexedInstrProfReader : public InstrProfReader {
/// Return the profile version.
uint64_t getVersion() const { return Index->getVersion(); }
bool isIRLevelProfile() const override { return Index->isIRLevelProfile(); }
bool hasCSIRLevelProfile() const override {
return Index->hasCSIRLevelProfile();
}

/// Return true if the given buffer is in an indexed instrprof format.
static bool hasFormat(const MemoryBuffer &DataBuffer);
Expand All @@ -450,7 +470,16 @@ class IndexedInstrProfReader : public InstrProfReader {
std::vector<uint64_t> &Counts);

/// Return the maximum of all known function counts.
uint64_t getMaximumFunctionCount() { return Summary->getMaxFunctionCount(); }
/// \c UseCS indicates whether to use the context-sensitive count.
uint64_t getMaximumFunctionCount(bool UseCS) {
if (UseCS) {
assert(CS_Summary && "No context sensitive profile summary");
return CS_Summary->getMaxFunctionCount();
} else {
assert(Summary && "No profile summary");
return Summary->getMaxFunctionCount();
}
}

/// Factory method to create an indexed reader.
static Expected<std::unique_ptr<IndexedInstrProfReader>>
Expand All @@ -469,7 +498,19 @@ class IndexedInstrProfReader : public InstrProfReader {
// to be used by llvm-profdata (for dumping). Avoid using this when
// the client is the compiler.
InstrProfSymtab &getSymtab() override;
ProfileSummary &getSummary() { return *(Summary.get()); }

/// Return the profile summary.
/// \c UseCS indicates whether to use the context-sensitive summary.
// TODO: removed the defualt parameter.
ProfileSummary &getSummary(bool UseCS = false) {
if (UseCS) {
assert(CS_Summary && "No context sensitive summary");
return *(CS_Summary.get());
} else {
assert(Summary && "No profile summary");
return *(Summary.get());
}
}
};

} // end namespace llvm
Expand Down
26 changes: 19 additions & 7 deletions include/llvm/ProfileData/InstrProfWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ class raw_fd_ostream;
class InstrProfWriter {
public:
using ProfilingData = SmallDenseMap<uint64_t, InstrProfRecord>;
enum ProfKind { PF_Unknown = 0, PF_FE, PF_IRLevel };
// PF_IRLevelWithCS is the profile from context sensitive IR instrumentation.
enum ProfKind { PF_Unknown = 0, PF_FE, PF_IRLevel, PF_IRLevelWithCS };

private:
bool Sparse;
Expand Down Expand Up @@ -74,15 +75,26 @@ class InstrProfWriter {
std::unique_ptr<MemoryBuffer> writeBuffer();

/// Set the ProfileKind. Report error if mixing FE and IR level profiles.
Error setIsIRLevelProfile(bool IsIRLevel) {
/// \c WithCS indicates if this is for contenxt sensitive instrumentation.
Error setIsIRLevelProfile(bool IsIRLevel, bool WithCS) {
if (ProfileKind == PF_Unknown) {
ProfileKind = IsIRLevel ? PF_IRLevel: PF_FE;
if (IsIRLevel)
ProfileKind = WithCS ? PF_IRLevelWithCS : PF_IRLevel;
else
ProfileKind = PF_FE;
return Error::success();
}
return (IsIRLevel == (ProfileKind == PF_IRLevel))
? Error::success()
: make_error<InstrProfError>(
instrprof_error::unsupported_version);

if (((ProfileKind != PF_FE) && !IsIRLevel) ||
((ProfileKind == PF_FE) && IsIRLevel))
return make_error<InstrProfError>(instrprof_error::unsupported_version);

// When merging a context-sensitive profile (WithCS == true) with an IRLevel
// profile, set the kind to PF_IRLevelWithCS.
if (ProfileKind == PF_IRLevel && WithCS)
ProfileKind = PF_IRLevelWithCS;

return Error::success();
}

// Internal interface for testing purpose only.
Expand Down
9 changes: 8 additions & 1 deletion lib/Analysis/ProfileSummaryInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,14 @@ static const ProfileSummaryEntry &getEntryForPercentile(SummaryEntryVector &DS,
bool ProfileSummaryInfo::computeSummary() {
if (Summary)
return true;
auto *SummaryMD = M.getProfileSummary();
// First try to get context sensitive ProfileSummary.
auto *SummaryMD = M.getProfileSummary(/* IsCS */ true);
if (SummaryMD) {
Summary.reset(ProfileSummary::getFromMD(SummaryMD));
return true;
}
// This will actually return PSK_Instr or PSK_Sample summary.
SummaryMD = M.getProfileSummary(/* IsCS */ false);
if (!SummaryMD)
return false;
Summary.reset(ProfileSummary::getFromMD(SummaryMD));
Expand Down
12 changes: 8 additions & 4 deletions lib/IR/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -531,12 +531,16 @@ void Module::setCodeModel(CodeModel::Model CL) {
addModuleFlag(ModFlagBehavior::Error, "Code Model", CL);
}

void Module::setProfileSummary(Metadata *M) {
addModuleFlag(ModFlagBehavior::Error, "ProfileSummary", M);
void Module::setProfileSummary(Metadata *M, ProfileSummary::Kind Kind) {
if (Kind == ProfileSummary::PSK_CSInstr)
addModuleFlag(ModFlagBehavior::Error, "CSProfileSummary", M);
else
addModuleFlag(ModFlagBehavior::Error, "ProfileSummary", M);
}

Metadata *Module::getProfileSummary() {
return getModuleFlag("ProfileSummary");
Metadata *Module::getProfileSummary(bool IsCS) {
return (IsCS ? getModuleFlag("CSProfileSummary")
: getModuleFlag("ProfileSummary"));
}

void Module::setOwnedMemoryBuffer(std::unique_ptr<MemoryBuffer> MB) {
Expand Down
6 changes: 4 additions & 2 deletions lib/IR/ProfileSummary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@

using namespace llvm;

const char *ProfileSummary::KindStr[2] = {"InstrProf", "SampleProfile"};

// 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,
Expand Down Expand Up @@ -68,6 +66,7 @@ Metadata *ProfileSummary::getDetailedSummaryMD(LLVMContext &Context) {
// "SampleProfile"). The rest of the elements of the outer MDTuple are specific
// to the kind of profile summary as returned by getFormatSpecificMD.
Metadata *ProfileSummary::getMD(LLVMContext &Context) {
const char *KindStr[3] = {"InstrProf", "CSInstrProf", "SampleProfile"};
Metadata *Components[] = {
getKeyValMD(Context, "ProfileFormat", KindStr[PSK]),
getKeyValMD(Context, "TotalCount", getTotalCount()),
Expand Down Expand Up @@ -153,6 +152,9 @@ ProfileSummary *ProfileSummary::getFromMD(Metadata *MD) {
else if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
"InstrProf"))
SummaryKind = PSK_Instr;
else if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
"CSInstrProf"))
SummaryKind = PSK_CSInstr;
else
return nullptr;

Expand Down
22 changes: 16 additions & 6 deletions lib/ProfileData/InstrProfReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,10 @@ Error TextInstrProfReader::readHeader() {
IsIRInstr = true;
else if (Str.equals_lower("fe"))
IsIRInstr = false;
else
else if (Str.equals_lower("csir")) {
IsIRInstr = true;
HasCSIRLevelProfile = true;
} else
return error(instrprof_error::bad_header);

++Line;
Expand Down Expand Up @@ -733,7 +736,7 @@ bool IndexedInstrProfReader::hasFormat(const MemoryBuffer &DataBuffer) {

const unsigned char *
IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,
const unsigned char *Cur) {
const unsigned char *Cur, bool UseCS) {
using namespace IndexedInstrProf;
using namespace support;

Expand All @@ -760,10 +763,13 @@ IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,
DetailedSummary.emplace_back((uint32_t)Ent.Cutoff, Ent.MinBlockCount,
Ent.NumBlocks);
}
std::unique_ptr<llvm::ProfileSummary> &Summary =
UseCS ? this->CS_Summary : this->Summary;

// initialize InstrProfSummary using the SummaryData from disk.
this->Summary = llvm::make_unique<ProfileSummary>(
ProfileSummary::PSK_Instr, DetailedSummary,
SummaryData->get(Summary::TotalBlockCount),
Summary = llvm::make_unique<ProfileSummary>(
UseCS ? ProfileSummary::PSK_CSInstr : ProfileSummary::PSK_Instr,
DetailedSummary, SummaryData->get(Summary::TotalBlockCount),
SummaryData->get(Summary::MaxBlockCount),
SummaryData->get(Summary::MaxInternalBlockCount),
SummaryData->get(Summary::MaxFunctionCount),
Expand Down Expand Up @@ -805,7 +811,11 @@ Error IndexedInstrProfReader::readHeader() {
IndexedInstrProf::ProfVersion::CurrentVersion)
return error(instrprof_error::unsupported_version);

Cur = readSummary((IndexedInstrProf::ProfVersion)FormatVersion, Cur);
Cur = readSummary((IndexedInstrProf::ProfVersion)FormatVersion, Cur,
/* UseCS */ false);
if (Header->Version & VARIANT_MASK_CSIR_PROF)
Cur = readSummary((IndexedInstrProf::ProfVersion)FormatVersion, Cur,
/* UseCS */ true);

// Read the hash type and start offset.
IndexedInstrProf::HashT HashType = static_cast<IndexedInstrProf::HashT>(
Expand Down
Loading

0 comments on commit 5af7fe3

Please sign in to comment.