diff options
Diffstat (limited to 'llvm/include')
-rw-r--r-- | llvm/include/llvm/Analysis/ProfileSummaryInfo.h | 6 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Module.h | 10 | ||||
-rw-r--r-- | llvm/include/llvm/IR/ProfileSummary.h | 3 | ||||
-rw-r--r-- | llvm/include/llvm/ProfileData/InstrProfReader.h | 47 | ||||
-rw-r--r-- | llvm/include/llvm/ProfileData/InstrProfWriter.h | 26 |
5 files changed, 77 insertions, 15 deletions
diff --git a/llvm/include/llvm/Analysis/ProfileSummaryInfo.h b/llvm/include/llvm/Analysis/ProfileSummaryInfo.h index 636b5d6876f..1b1112f1a66 100644 --- a/llvm/include/llvm/Analysis/ProfileSummaryInfo.h +++ b/llvm/include/llvm/Analysis/ProfileSummaryInfo.h @@ -73,6 +73,12 @@ public: 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 diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h index 7373b848541..40c0db5e00c 100644 --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -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" @@ -868,10 +869,13 @@ public: /// @{ /// 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. diff --git a/llvm/include/llvm/IR/ProfileSummary.h b/llvm/include/llvm/IR/ProfileSummary.h index f1d49cc1663..78635ec4386 100644 --- a/llvm/include/llvm/IR/ProfileSummary.h +++ b/llvm/include/llvm/IR/ProfileSummary.h @@ -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; diff --git a/llvm/include/llvm/ProfileData/InstrProfReader.h b/llvm/include/llvm/ProfileData/InstrProfReader.h index d465420f3d6..25f9df03321 100644 --- a/llvm/include/llvm/ProfileData/InstrProfReader.h +++ b/llvm/include/llvm/ProfileData/InstrProfReader.h @@ -77,6 +77,8 @@ public: 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 @@ -142,6 +144,7 @@ private: /// Iterator over the profile data. line_iterator Line; bool IsIRLevelProfile = false; + bool HasCSIRLevelProfile = false; Error readValueProfileData(InstrProfRecord &Record); @@ -156,6 +159,8 @@ public: bool isIRLevelProfile() const override { return IsIRLevelProfile; } + bool hasCSIRLevelProfile() const override { return HasCSIRLevelProfile; } + /// Read the header. Error readHeader() override; @@ -212,6 +217,10 @@ public: 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(); @@ -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; }; @@ -385,6 +395,10 @@ public: 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()); } @@ -412,13 +426,16 @@ private: 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( @@ -432,6 +449,9 @@ public: /// 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); @@ -450,7 +470,16 @@ public: 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>> @@ -469,7 +498,19 @@ public: // 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 diff --git a/llvm/include/llvm/ProfileData/InstrProfWriter.h b/llvm/include/llvm/ProfileData/InstrProfWriter.h index b0ab31ddfc3..a972ff8a66e 100644 --- a/llvm/include/llvm/ProfileData/InstrProfWriter.h +++ b/llvm/include/llvm/ProfileData/InstrProfWriter.h @@ -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; @@ -74,15 +75,26 @@ public: 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. |