X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FProfileData%2FInstrProf.h;h=49569d89507b482cd187e4be47977d6d41930c47;hb=8d08283a5affcdd34ea709c4c17f05803d6df3d5;hp=b0d08a5886f887f458999565ac906c19ec695fe2;hpb=bde8257dd75bee89b48f3e1975298517602a01e0;p=oota-llvm.git diff --git a/include/llvm/ProfileData/InstrProf.h b/include/llvm/ProfileData/InstrProf.h index b0d08a5886f..49569d89507 100644 --- a/include/llvm/ProfileData/InstrProf.h +++ b/include/llvm/ProfileData/InstrProf.h @@ -155,11 +155,36 @@ GlobalVariable *createPGOFuncNameVar(Function &F, StringRef FuncName); GlobalVariable *createPGOFuncNameVar(Module &M, GlobalValue::LinkageTypes Linkage, StringRef FuncName); +/// Return the initializer in string of the PGO name var \c NameVar. +StringRef getPGOFuncNameVarInitializer(GlobalVariable *NameVar); /// Given a PGO function name, remove the filename prefix and return /// the original (static) function name. StringRef getFuncNameWithoutPrefix(StringRef PGOFuncName, StringRef FileName); +/// Given a vector of strings (function PGO names) \c NameStrs, the +/// method generates a combined string \c Result thatis ready to be +/// serialized. The \c Result string is comprised of three fields: +/// The first field is the legnth of the uncompressed strings, and the +/// the second field is the length of the zlib-compressed string. +/// Both fields are encoded in ULEB128. If \c doCompress is false, the +/// third field is the uncompressed strings; otherwise it is the +/// compressed string. When the string compression is off, the +/// second field will have value zero. +int collectPGOFuncNameStrings(const std::vector &NameStrs, + bool doCompression, std::string &Result); +/// Produce \c Result string with the same format described above. The input +/// is vector of PGO function name variables that are referenced. +int collectPGOFuncNameStrings(const std::vector &NameVars, + std::string &Result); +class InstrProfSymtab; +/// \c NameStrings is a string composed of one of more sub-strings encoded in +/// the +/// format described above. The substrings are seperated by 0 or more zero +/// bytes. +/// This method decodes the string and populates the \c Symtab. +int readPGOFuncNameStrings(StringRef NameStrings, InstrProfSymtab &Symtab); + const std::error_category &instrprof_category(); enum class instrprof_error { @@ -202,49 +227,111 @@ enum InstrProfValueKind : uint32_t { namespace object { class SectionRef; } + +namespace IndexedInstrProf { +uint64_t ComputeHash(StringRef K); +} + /// A symbol table used for function PGO name look-up with keys /// (such as pointers, md5hash values) to the function. A function's /// PGO name or name's md5hash are used in retrieving the profile /// data of the function. See \c getPGOFuncName() method for details /// on how PGO name is formed. class InstrProfSymtab { +public: + typedef std::vector> AddrHashMap; + private: StringRef Data; uint64_t Address; + // A map from MD5 hash keys to function name strings. + std::vector> HashNameMap; + // A map from function runtime address to function name MD5 hash. + // This map is only populated and used by raw instr profile reader. + AddrHashMap AddrToMD5Map; public: - InstrProfSymtab() : Data(), Address(0) {} + InstrProfSymtab() : Data(), Address(0), HashNameMap(), AddrToMD5Map() {} - /// Create InstrProfSymtab from a object file section which + /// Create InstrProfSymtab from an object file section which /// contains function PGO names that are uncompressed. + /// This interface is used by CoverageMappingReader. std::error_code create(object::SectionRef &Section); - std::error_code create(StringRef D, uint64_t BaseAddr) { - Data = D; - Address = BaseAddr; - return std::error_code(); + /// This interface is used by reader of CoverageMapping test + /// format. + inline std::error_code create(StringRef D, uint64_t BaseAddr); + /// \c NameStrings is a string composed of one of more sub-strings + /// encoded in the format described above. The substrings are + /// seperated by 0 or more zero bytes. This method decodes the + /// string and populates the \c Symtab. + inline std::error_code create(StringRef NameStrings); + /// Create InstrProfSymtab from a set of names iteratable from + /// \p IterRange. This interface is used by IndexedProfReader. + template void create(const NameIterRange &IterRange); + // If the symtab is created by a series of calls to \c addFuncName, \c + // finalizeSymtab needs to be called before looking up function names. + // This is required because the underlying map is a vector (for space + // efficiency) which needs to be sorted. + inline void finalizeSymtab(); + /// Update the symtab by adding \p FuncName to the table. This interface + /// is used by the raw and text profile readers. + void addFuncName(StringRef FuncName) { + HashNameMap.push_back(std::make_pair( + IndexedInstrProf::ComputeHash(FuncName), FuncName.str())); } - - /// Return function's PGO name from the function name's symabol - /// address in the object file. If an error occurs, Return + /// Map a function address to its name's MD5 hash. This interface + /// is only used by the raw profiler reader. + void mapAddress(uint64_t Addr, uint64_t MD5Val) { + AddrToMD5Map.push_back(std::make_pair(Addr, MD5Val)); + } + AddrHashMap &getAddrHashMap() { return AddrToMD5Map; } + /// Return function's PGO name from the function name's symbol + /// address in the object file. If an error occurs, return /// an empty string. StringRef getFuncName(uint64_t FuncNameAddress, size_t NameSize); + /// Return function's PGO name from the name's md5 hash value. + /// If not found, return an empty string. + inline StringRef getFuncName(uint64_t FuncMD5Hash); }; -struct InstrProfStringTable { - // Set of string values in profiling data. - StringSet<> StringValueSet; - InstrProfStringTable() { StringValueSet.clear(); } - // Get a pointer to internal storage of a string in set - const char *getStringData(StringRef Str) { - auto Result = StringValueSet.find(Str); - return (Result == StringValueSet.end()) ? nullptr : Result->first().data(); - } - // Insert a string to StringTable - const char *insertString(StringRef Str) { - auto Result = StringValueSet.insert(Str); - return Result.first->first().data(); - } -}; +std::error_code InstrProfSymtab::create(StringRef D, uint64_t BaseAddr) { + Data = D; + Address = BaseAddr; + return std::error_code(); +} + +std::error_code InstrProfSymtab::create(StringRef NameStrings) { + if (readPGOFuncNameStrings(NameStrings, *this)) + return make_error_code(instrprof_error::malformed); + return std::error_code(); +} + +template +void InstrProfSymtab::create(const NameIterRange &IterRange) { + for (auto Name : IterRange) + HashNameMap.push_back( + std::make_pair(IndexedInstrProf::ComputeHash(Name), Name.str())); + finalizeSymtab(); +} + +void InstrProfSymtab::finalizeSymtab() { + std::sort(HashNameMap.begin(), HashNameMap.end(), less_first()); + HashNameMap.erase(std::unique(HashNameMap.begin(), HashNameMap.end()), + HashNameMap.end()); + std::sort(AddrToMD5Map.begin(), AddrToMD5Map.end(), less_first()); + AddrToMD5Map.erase(std::unique(AddrToMD5Map.begin(), AddrToMD5Map.end()), + AddrToMD5Map.end()); +} + +StringRef InstrProfSymtab::getFuncName(uint64_t FuncMD5Hash) { + auto Result = + std::lower_bound(HashNameMap.begin(), HashNameMap.end(), FuncMD5Hash, + [](const std::pair &LHS, + uint64_t RHS) { return LHS.first < RHS; }); + if (Result != HashNameMap.end()) + return Result->second; + return StringRef(); +} struct InstrProfValueSiteRecord { /// Value profiling data pairs at a given value site. @@ -266,34 +353,7 @@ struct InstrProfValueSiteRecord { /// Merge data from another InstrProfValueSiteRecord /// Optionally scale merged counts by \p Weight. instrprof_error mergeValueData(InstrProfValueSiteRecord &Input, - uint64_t Weight = 1) { - this->sortByTargetValues(); - Input.sortByTargetValues(); - auto I = ValueData.begin(); - auto IE = ValueData.end(); - instrprof_error Result = instrprof_error::success; - for (auto J = Input.ValueData.begin(), JE = Input.ValueData.end(); J != JE; - ++J) { - while (I != IE && I->Value < J->Value) - ++I; - if (I != IE && I->Value == J->Value) { - uint64_t JCount = J->Count; - bool Overflowed; - if (Weight > 1) { - JCount = SaturatingMultiply(JCount, Weight, &Overflowed); - if (Overflowed) - Result = instrprof_error::counter_overflow; - } - I->Count = SaturatingAdd(I->Count, JCount, &Overflowed); - if (Overflowed) - Result = instrprof_error::counter_overflow; - ++I; - continue; - } - ValueData.insert(I, *J); - } - return Result; - } + uint64_t Weight = 1); }; /// Profiling information for a single function. @@ -305,7 +365,7 @@ struct InstrProfRecord { uint64_t Hash; std::vector Counts; - typedef std::vector> ValueMapType; + typedef std::vector> ValueMapType; /// Return the number of value profile kinds with non-zero number /// of profile sites. @@ -330,16 +390,12 @@ struct InstrProfRecord { /// Add ValueData for ValueKind at value Site. void addValueData(uint32_t ValueKind, uint32_t Site, InstrProfValueData *VData, uint32_t N, - ValueMapType *HashKeys); + ValueMapType *ValueMap); /// Merge the counts in \p Other into this one. /// Optionally scale merged counts by \p Weight. instrprof_error merge(InstrProfRecord &Other, uint64_t Weight = 1); - /// Used by InstrProfWriter: update the value strings to commoned strings in - /// the writer instance. - void updateStrings(InstrProfStringTable *StrTab); - /// Clear value data entries void clearValueData() { for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) @@ -481,7 +537,7 @@ static inline uint64_t MD5Hash(StringRef Str) { return endian::read(Result); } -static inline uint64_t ComputeHash(HashT Type, StringRef K) { +inline uint64_t ComputeHash(HashT Type, StringRef K) { switch (Type) { case HashT::MD5: return IndexedInstrProf::MD5Hash(K); @@ -493,9 +549,7 @@ const uint64_t Magic = 0x8169666f72706cff; // "\xfflprofi\x81" const uint64_t Version = INSTR_PROF_INDEX_VERSION; const HashT HashType = HashT::MD5; -static inline uint64_t ComputeHash(StringRef K) { - return ComputeHash(HashType, K); -} +inline uint64_t ComputeHash(StringRef K) { return ComputeHash(HashType, K); } // This structure defines the file header of the LLVM profile // data file in indexed-format. @@ -558,8 +612,14 @@ template struct CovMapFunctionRecord { #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name; #include "llvm/ProfileData/InstrProfData.inc" }; -LLVM_PACKED_END +// Per module coverage mapping data header, i.e. CoverageMapFileHeader +// documented above. +struct CovMapHeader { +#define COVMAP_HEADER(Type, LLVMType, Name, Init) Type Name; +#include "llvm/ProfileData/InstrProfData.inc" +}; +LLVM_PACKED_END } } // end namespace llvm