Skip to content

Commit a6ff69f

Browse files
committed
[PGO] Context sensitive PGO (part 2)
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 llvm-svn: 355131
1 parent 7fc6ef7 commit a6ff69f

17 files changed

+182
-47
lines changed

llvm/docs/CommandGuide/llvm-profdata.rst

+4
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,10 @@ OPTIONS
226226
Only output names of functions whose max count value are below the cutoff
227227
value.
228228

229+
.. option:: -showcs
230+
Only show context sensitive profile counts. The default is to filter all
231+
context sensitive profile counts.
232+
229233
EXIT STATUS
230234
-----------
231235

llvm/include/llvm/Analysis/ProfileSummaryInfo.h

+6
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,12 @@ class ProfileSummaryInfo {
7373
Summary->getKind() == ProfileSummary::PSK_Instr;
7474
}
7575

76+
/// Returns true if module \c M has context sensitive instrumentation profile.
77+
bool hasCSInstrumentationProfile() {
78+
return hasProfileSummary() &&
79+
Summary->getKind() == ProfileSummary::PSK_CSInstr;
80+
}
81+
7682
/// Handle the invalidation of this information.
7783
///
7884
/// When used as a result of \c ProfileSummaryAnalysis this method will be

llvm/include/llvm/IR/Module.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "llvm/IR/GlobalIFunc.h"
2929
#include "llvm/IR/GlobalVariable.h"
3030
#include "llvm/IR/Metadata.h"
31+
#include "llvm/IR/ProfileSummary.h"
3132
#include "llvm/IR/SymbolTableListTraits.h"
3233
#include "llvm/Support/CBindingWrapping.h"
3334
#include "llvm/Support/CodeGen.h"
@@ -868,10 +869,13 @@ class Module {
868869
/// @{
869870

870871
/// Attach profile summary metadata to this module.
871-
void setProfileSummary(Metadata *M);
872+
// TODO: Remove the default paramter.
873+
void setProfileSummary(Metadata *M,
874+
ProfileSummary::Kind Kind = ProfileSummary::PSK_Instr);
872875

873-
/// Returns profile summary metadata
874-
Metadata *getProfileSummary();
876+
/// Returns profile summary metadata. When IsCS is true, use the context
877+
/// sensitive profile summary.
878+
Metadata *getProfileSummary(bool IsCS);
875879
/// @}
876880

877881
/// Returns true if PLT should be avoided for RTLib calls.

llvm/include/llvm/IR/ProfileSummary.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,10 @@ using SummaryEntryVector = std::vector<ProfileSummaryEntry>;
4242

4343
class ProfileSummary {
4444
public:
45-
enum Kind { PSK_Instr, PSK_Sample };
45+
enum Kind { PSK_Instr, PSK_CSInstr, PSK_Sample };
4646

4747
private:
4848
const Kind PSK;
49-
static const char *KindStr[2];
5049
SummaryEntryVector DetailedSummary;
5150
uint64_t TotalCount, MaxCount, MaxInternalCount, MaxFunctionCount;
5251
uint32_t NumCounts, NumFunctions;

llvm/include/llvm/ProfileData/InstrProfReader.h

+44-3
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ class InstrProfReader {
7777

7878
virtual bool isIRLevelProfile() const = 0;
7979

80+
virtual bool hasCSIRLevelProfile() const = 0;
81+
8082
/// Return the PGO symtab. There are three different readers:
8183
/// Raw, Text, and Indexed profile readers. The first two types
8284
/// of readers are used only by llvm-profdata tool, while the indexed
@@ -142,6 +144,7 @@ class TextInstrProfReader : public InstrProfReader {
142144
/// Iterator over the profile data.
143145
line_iterator Line;
144146
bool IsIRLevelProfile = false;
147+
bool HasCSIRLevelProfile = false;
145148

146149
Error readValueProfileData(InstrProfRecord &Record);
147150

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

157160
bool isIRLevelProfile() const override { return IsIRLevelProfile; }
158161

162+
bool hasCSIRLevelProfile() const override { return HasCSIRLevelProfile; }
163+
159164
/// Read the header.
160165
Error readHeader() override;
161166

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

220+
bool hasCSIRLevelProfile() const override {
221+
return (Version & VARIANT_MASK_CSIR_PROF) != 0;
222+
}
223+
215224
InstrProfSymtab &getSymtab() override {
216225
assert(Symtab.get());
217226
return *Symtab.get();
@@ -341,6 +350,7 @@ struct InstrProfReaderIndexBase {
341350
virtual void setValueProfDataEndianness(support::endianness Endianness) = 0;
342351
virtual uint64_t getVersion() const = 0;
343352
virtual bool isIRLevelProfile() const = 0;
353+
virtual bool hasCSIRLevelProfile() const = 0;
344354
virtual Error populateSymtab(InstrProfSymtab &) = 0;
345355
};
346356

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

398+
bool hasCSIRLevelProfile() const override {
399+
return (FormatVersion & VARIANT_MASK_CSIR_PROF) != 0;
400+
}
401+
388402
Error populateSymtab(InstrProfSymtab &Symtab) override {
389403
return Symtab.create(HashTable->keys());
390404
}
@@ -412,13 +426,16 @@ class IndexedInstrProfReader : public InstrProfReader {
412426
std::unique_ptr<InstrProfReaderRemapper> Remapper;
413427
/// Profile summary data.
414428
std::unique_ptr<ProfileSummary> Summary;
429+
/// Context sensitive profile summary data.
430+
std::unique_ptr<ProfileSummary> CS_Summary;
415431
// Index to the current record in the record array.
416432
unsigned RecordIndex;
417433

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

423440
public:
424441
IndexedInstrProfReader(
@@ -432,6 +449,9 @@ class IndexedInstrProfReader : public InstrProfReader {
432449
/// Return the profile version.
433450
uint64_t getVersion() const { return Index->getVersion(); }
434451
bool isIRLevelProfile() const override { return Index->isIRLevelProfile(); }
452+
bool hasCSIRLevelProfile() const override {
453+
return Index->hasCSIRLevelProfile();
454+
}
435455

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

452472
/// Return the maximum of all known function counts.
453-
uint64_t getMaximumFunctionCount() { return Summary->getMaxFunctionCount(); }
473+
/// \c UseCS indicates whether to use the context-sensitive count.
474+
uint64_t getMaximumFunctionCount(bool UseCS) {
475+
if (UseCS) {
476+
assert(CS_Summary && "No context sensitive profile summary");
477+
return CS_Summary->getMaxFunctionCount();
478+
} else {
479+
assert(Summary && "No profile summary");
480+
return Summary->getMaxFunctionCount();
481+
}
482+
}
454483

455484
/// Factory method to create an indexed reader.
456485
static Expected<std::unique_ptr<IndexedInstrProfReader>>
@@ -469,7 +498,19 @@ class IndexedInstrProfReader : public InstrProfReader {
469498
// to be used by llvm-profdata (for dumping). Avoid using this when
470499
// the client is the compiler.
471500
InstrProfSymtab &getSymtab() override;
472-
ProfileSummary &getSummary() { return *(Summary.get()); }
501+
502+
/// Return the profile summary.
503+
/// \c UseCS indicates whether to use the context-sensitive summary.
504+
// TODO: removed the defualt parameter.
505+
ProfileSummary &getSummary(bool UseCS = false) {
506+
if (UseCS) {
507+
assert(CS_Summary && "No context sensitive summary");
508+
return *(CS_Summary.get());
509+
} else {
510+
assert(Summary && "No profile summary");
511+
return *(Summary.get());
512+
}
513+
}
473514
};
474515

475516
} // end namespace llvm

llvm/include/llvm/ProfileData/InstrProfWriter.h

+19-7
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ class raw_fd_ostream;
3333
class InstrProfWriter {
3434
public:
3535
using ProfilingData = SmallDenseMap<uint64_t, InstrProfRecord>;
36-
enum ProfKind { PF_Unknown = 0, PF_FE, PF_IRLevel };
36+
// PF_IRLevelWithCS is the profile from context sensitive IR instrumentation.
37+
enum ProfKind { PF_Unknown = 0, PF_FE, PF_IRLevel, PF_IRLevelWithCS };
3738

3839
private:
3940
bool Sparse;
@@ -74,15 +75,26 @@ class InstrProfWriter {
7475
std::unique_ptr<MemoryBuffer> writeBuffer();
7576

7677
/// Set the ProfileKind. Report error if mixing FE and IR level profiles.
77-
Error setIsIRLevelProfile(bool IsIRLevel) {
78+
/// \c WithCS indicates if this is for contenxt sensitive instrumentation.
79+
Error setIsIRLevelProfile(bool IsIRLevel, bool WithCS) {
7880
if (ProfileKind == PF_Unknown) {
79-
ProfileKind = IsIRLevel ? PF_IRLevel: PF_FE;
81+
if (IsIRLevel)
82+
ProfileKind = WithCS ? PF_IRLevelWithCS : PF_IRLevel;
83+
else
84+
ProfileKind = PF_FE;
8085
return Error::success();
8186
}
82-
return (IsIRLevel == (ProfileKind == PF_IRLevel))
83-
? Error::success()
84-
: make_error<InstrProfError>(
85-
instrprof_error::unsupported_version);
87+
88+
if (((ProfileKind != PF_FE) && !IsIRLevel) ||
89+
((ProfileKind == PF_FE) && IsIRLevel))
90+
return make_error<InstrProfError>(instrprof_error::unsupported_version);
91+
92+
// When merging a context-sensitive profile (WithCS == true) with an IRLevel
93+
// profile, set the kind to PF_IRLevelWithCS.
94+
if (ProfileKind == PF_IRLevel && WithCS)
95+
ProfileKind = PF_IRLevelWithCS;
96+
97+
return Error::success();
8698
}
8799

88100
// Internal interface for testing purpose only.

llvm/lib/Analysis/ProfileSummaryInfo.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,14 @@ static const ProfileSummaryEntry &getEntryForPercentile(SummaryEntryVector &DS,
7979
bool ProfileSummaryInfo::computeSummary() {
8080
if (Summary)
8181
return true;
82-
auto *SummaryMD = M.getProfileSummary();
82+
// First try to get context sensitive ProfileSummary.
83+
auto *SummaryMD = M.getProfileSummary(/* IsCS */ true);
84+
if (SummaryMD) {
85+
Summary.reset(ProfileSummary::getFromMD(SummaryMD));
86+
return true;
87+
}
88+
// This will actually return PSK_Instr or PSK_Sample summary.
89+
SummaryMD = M.getProfileSummary(/* IsCS */ false);
8390
if (!SummaryMD)
8491
return false;
8592
Summary.reset(ProfileSummary::getFromMD(SummaryMD));

llvm/lib/IR/Module.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -531,12 +531,16 @@ void Module::setCodeModel(CodeModel::Model CL) {
531531
addModuleFlag(ModFlagBehavior::Error, "Code Model", CL);
532532
}
533533

534-
void Module::setProfileSummary(Metadata *M) {
535-
addModuleFlag(ModFlagBehavior::Error, "ProfileSummary", M);
534+
void Module::setProfileSummary(Metadata *M, ProfileSummary::Kind Kind) {
535+
if (Kind == ProfileSummary::PSK_CSInstr)
536+
addModuleFlag(ModFlagBehavior::Error, "CSProfileSummary", M);
537+
else
538+
addModuleFlag(ModFlagBehavior::Error, "ProfileSummary", M);
536539
}
537540

538-
Metadata *Module::getProfileSummary() {
539-
return getModuleFlag("ProfileSummary");
541+
Metadata *Module::getProfileSummary(bool IsCS) {
542+
return (IsCS ? getModuleFlag("CSProfileSummary")
543+
: getModuleFlag("ProfileSummary"));
540544
}
541545

542546
void Module::setOwnedMemoryBuffer(std::unique_ptr<MemoryBuffer> MB) {

llvm/lib/IR/ProfileSummary.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121

2222
using namespace llvm;
2323

24-
const char *ProfileSummary::KindStr[2] = {"InstrProf", "SampleProfile"};
25-
2624
// Return an MDTuple with two elements. The first element is a string Key and
2725
// the second is a uint64_t Value.
2826
static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
@@ -68,6 +66,7 @@ Metadata *ProfileSummary::getDetailedSummaryMD(LLVMContext &Context) {
6866
// "SampleProfile"). The rest of the elements of the outer MDTuple are specific
6967
// to the kind of profile summary as returned by getFormatSpecificMD.
7068
Metadata *ProfileSummary::getMD(LLVMContext &Context) {
69+
const char *KindStr[3] = {"InstrProf", "CSInstrProf", "SampleProfile"};
7170
Metadata *Components[] = {
7271
getKeyValMD(Context, "ProfileFormat", KindStr[PSK]),
7372
getKeyValMD(Context, "TotalCount", getTotalCount()),
@@ -153,6 +152,9 @@ ProfileSummary *ProfileSummary::getFromMD(Metadata *MD) {
153152
else if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
154153
"InstrProf"))
155154
SummaryKind = PSK_Instr;
155+
else if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
156+
"CSInstrProf"))
157+
SummaryKind = PSK_CSInstr;
156158
else
157159
return nullptr;
158160

llvm/lib/ProfileData/InstrProfReader.cpp

+16-6
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,10 @@ Error TextInstrProfReader::readHeader() {
162162
IsIRInstr = true;
163163
else if (Str.equals_lower("fe"))
164164
IsIRInstr = false;
165-
else
165+
else if (Str.equals_lower("csir")) {
166+
IsIRInstr = true;
167+
HasCSIRLevelProfile = true;
168+
} else
166169
return error(instrprof_error::bad_header);
167170

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

734737
const unsigned char *
735738
IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,
736-
const unsigned char *Cur) {
739+
const unsigned char *Cur, bool UseCS) {
737740
using namespace IndexedInstrProf;
738741
using namespace support;
739742

@@ -760,10 +763,13 @@ IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,
760763
DetailedSummary.emplace_back((uint32_t)Ent.Cutoff, Ent.MinBlockCount,
761764
Ent.NumBlocks);
762765
}
766+
std::unique_ptr<llvm::ProfileSummary> &Summary =
767+
UseCS ? this->CS_Summary : this->Summary;
768+
763769
// initialize InstrProfSummary using the SummaryData from disk.
764-
this->Summary = llvm::make_unique<ProfileSummary>(
765-
ProfileSummary::PSK_Instr, DetailedSummary,
766-
SummaryData->get(Summary::TotalBlockCount),
770+
Summary = llvm::make_unique<ProfileSummary>(
771+
UseCS ? ProfileSummary::PSK_CSInstr : ProfileSummary::PSK_Instr,
772+
DetailedSummary, SummaryData->get(Summary::TotalBlockCount),
767773
SummaryData->get(Summary::MaxBlockCount),
768774
SummaryData->get(Summary::MaxInternalBlockCount),
769775
SummaryData->get(Summary::MaxFunctionCount),
@@ -805,7 +811,11 @@ Error IndexedInstrProfReader::readHeader() {
805811
IndexedInstrProf::ProfVersion::CurrentVersion)
806812
return error(instrprof_error::unsupported_version);
807813

808-
Cur = readSummary((IndexedInstrProf::ProfVersion)FormatVersion, Cur);
814+
Cur = readSummary((IndexedInstrProf::ProfVersion)FormatVersion, Cur,
815+
/* UseCS */ false);
816+
if (Header->Version & VARIANT_MASK_CSIR_PROF)
817+
Cur = readSummary((IndexedInstrProf::ProfVersion)FormatVersion, Cur,
818+
/* UseCS */ true);
809819

810820
// Read the hash type and start offset.
811821
IndexedInstrProf::HashT HashType = static_cast<IndexedInstrProf::HashT>(

0 commit comments

Comments
 (0)