X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=include%2Fllvm%2FProfileData%2FInstrProf.h;h=2be174d573d0b524854c080222c5353f978da198;hp=f425c6e13ed30343b4538c936715b50329451539;hb=6eef6fc8593a2d3909c168b0fcd9027b40c5c6f8;hpb=09717fa07bf6a4cc529885ccb33c8751519efd22 diff --git a/include/llvm/ProfileData/InstrProf.h b/include/llvm/ProfileData/InstrProf.h index f425c6e13ed..2be174d573d 100644 --- a/include/llvm/ProfileData/InstrProf.h +++ b/include/llvm/ProfileData/InstrProf.h @@ -27,6 +27,92 @@ #include namespace llvm { + +/// Return the name of data section containing profile counter variables. +inline StringRef getInstrProfCountersSectionName(bool AddSegment) { + return AddSegment ? "__DATA,__llvm_prf_cnts" : "__llvm_prf_cnts"; +} + +/// Return the name of data section containing names of instrumented +/// functions. +inline StringRef getInstrProfNameSectionName(bool AddSegment) { + return AddSegment ? "__DATA,__llvm_prf_names" : "__llvm_prf_names"; +} + +/// Return the name of the data section containing per-function control +/// data. +inline StringRef getInstrProfDataSectionName(bool AddSegment) { + return AddSegment ? "__DATA,__llvm_prf_data" : "__llvm_prf_data"; +} + +/// Return the name of the section containing function coverage mapping +/// data. +inline StringRef getInstrProfCoverageSectionName(bool AddSegment) { + return AddSegment ? "__DATA,__llvm_covmap" : "__llvm_covmap"; +} + +/// Return the name prefix of variables containing instrumented function names. +inline StringRef getInstrProfNameVarPrefix() { return "__llvm_profile_name_"; } + +/// Return the name prefix of variables containing per-function control data. +inline StringRef getInstrProfDataVarPrefix() { return "__llvm_profile_data_"; } + +/// Return the name prefix of profile counter variables. +inline StringRef getInstrProfCountersVarPrefix() { + return "__llvm_profile_counters_"; +} + +/// Return the name prefix of the COMDAT group for instrumentation variables +/// associated with a COMDAT function. +inline StringRef getInstrProfComdatPrefix() { return "__llvm_profile_vars_"; } + +/// Return the name of a covarage mapping variable (internal linkage) +/// for each instrumented source module. Such variables are allocated +/// in the __llvm_covmap section. +inline StringRef getCoverageMappingVarName() { + return "__llvm_coverage_mapping"; +} + +/// Return the name of function that registers all the per-function control +/// data at program startup time by calling __llvm_register_function. This +/// function has internal linkage and is called by __llvm_profile_init +/// runtime method. This function is not generated for these platforms: +/// Darwin, Linux, and FreeBSD. +inline StringRef getInstrProfRegFuncsName() { + return "__llvm_profile_register_functions"; +} + +/// Return the name of the runtime interface that registers per-function control +/// data for one instrumented function. +inline StringRef getInstrProfRegFuncName() { + return "__llvm_profile_register_function"; +} + +/// Return the name of the runtime initialization method that is generated by +/// the compiler. The function calls __llvm_profile_register_functions and +/// __llvm_profile_override_default_filename functions if needed. This function +/// has internal linkage and invoked at startup time via init_array. +inline StringRef getInstrProfInitFuncName() { return "__llvm_profile_init"; } + +/// Return the name of the hook variable defined in profile runtime library. +/// A reference to the variable causes the linker to link in the runtime +/// initialization module (which defines the hook variable). +inline StringRef getInstrProfRuntimeHookVarName() { + return "__llvm_profile_runtime"; +} + +/// Return the name of the compiler generated function that references the +/// runtime hook variable. The function is a weak global. +inline StringRef getInstrProfRuntimeHookVarUseFuncName() { + return "__llvm_profile_runtime_user"; +} + +/// Return the name of the profile runtime interface that overrides the default +/// profile data file name. +inline StringRef getInstrProfFileOverriderFuncName() { + return "__llvm_profile_override_default_filename"; +} + const std::error_category &instrprof_category(); enum class instrprof_error { @@ -73,19 +159,28 @@ struct InstrProfStringTable { } }; +struct InstrProfValueData { + // Profiled value. + uint64_t Value; + // Number of times the value appears in the training run. + uint64_t Count; +}; + struct InstrProfValueSiteRecord { - /// Typedef for a single TargetValue-NumTaken pair. - typedef std::pair ValueDataPair; /// Value profiling data pairs at a given value site. - std::list ValueData; + std::list ValueData; InstrProfValueSiteRecord() { ValueData.clear(); } + template + InstrProfValueSiteRecord(InputIterator F, InputIterator L) + : ValueData(F, L) {} - /// Sort ValueData ascending by TargetValue + /// Sort ValueData ascending by Value void sortByTargetValues() { - ValueData.sort([](const ValueDataPair &left, const ValueDataPair &right) { - return left.first < right.first; - }); + ValueData.sort( + [](const InstrProfValueData &left, const InstrProfValueData &right) { + return left.Value < right.Value; + }); } /// Merge data from another InstrProfValueSiteRecord @@ -96,10 +191,9 @@ struct InstrProfValueSiteRecord { auto IE = ValueData.end(); for (auto J = Input.ValueData.begin(), JE = Input.ValueData.end(); J != JE; ++J) { - while (I != IE && I->first < J->first) - ++I; - if (I != IE && I->first == J->first) { - I->second += J->second; + while (I != IE && I->Value < J->Value) ++I; + if (I != IE && I->Value == J->Value) { + I->Count += J->Count; ++I; continue; } @@ -116,15 +210,47 @@ struct InstrProfRecord { StringRef Name; uint64_t Hash; std::vector Counts; - std::vector IndirectCallSites; + typedef std::vector> ValueMapType; + + /// Return the number of value profile kinds with non-zero number + /// of profile sites. + inline uint32_t getNumValueKinds() const; + /// Return the number of instrumented sites for ValueKind. + inline uint32_t getNumValueSites(uint32_t ValueKind) const; + /// Return the total number of ValueData for ValueKind. + inline uint32_t getNumValueData(uint32_t ValueKind) const; + /// Return the number of value data collected for ValueKind at profiling + /// site: Site. + inline uint32_t getNumValueDataForSite(uint32_t ValueKind, + uint32_t Site) const; + inline std::unique_ptr getValueForSite( + uint32_t ValueKind, uint32_t Site) const; + /// Reserve space for NumValueSites sites. + inline void reserveSites(uint32_t ValueKind, uint32_t NumValueSites); + /// Add ValueData for ValueKind at value Site. + inline void addValueData(uint32_t ValueKind, uint32_t Site, + InstrProfValueData *VData, uint32_t N, + ValueMapType *HashKeys); + /// Merge Value Profile ddata from Src record to this record for ValueKind. + inline instrprof_error mergeValueProfData(uint32_t ValueKind, + InstrProfRecord &Src); + + /// Used by InstrProfWriter: update the value strings to commoned strings in + /// the writer instance. + inline void updateStrings(InstrProfStringTable *StrTab); + + private: + std::vector IndirectCallSites; const std::vector & getValueSitesForKind(uint32_t ValueKind) const { switch (ValueKind) { case IPVK_IndirectCallTarget: return IndirectCallSites; + default: + llvm_unreachable("Unknown value kind!"); } - llvm_unreachable("Unknown value kind!"); + return IndirectCallSites; } std::vector & @@ -133,8 +259,102 @@ struct InstrProfRecord { const_cast(this) ->getValueSitesForKind(ValueKind)); } + // Map indirect call target name hash to name string. + uint64_t remapValue(uint64_t Value, uint32_t ValueKind, + ValueMapType *HashKeys) { + if (!HashKeys) return Value; + switch (ValueKind) { + case IPVK_IndirectCallTarget: { + auto Result = + std::lower_bound(HashKeys->begin(), HashKeys->end(), Value, + [](const std::pair &LHS, + uint64_t RHS) { return LHS.first < RHS; }); + assert(Result != HashKeys->end() && + "Hash does not match any known keys\n"); + Value = (uint64_t)Result->second; + break; + } + } + return Value; + } }; +uint32_t InstrProfRecord::getNumValueKinds() const { + uint32_t NumValueKinds = 0; + for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) + NumValueKinds += !(getValueSitesForKind(Kind).empty()); + return NumValueKinds; +} + +uint32_t InstrProfRecord::getNumValueSites(uint32_t ValueKind) const { + return getValueSitesForKind(ValueKind).size(); +} + +uint32_t InstrProfRecord::getNumValueDataForSite(uint32_t ValueKind, + uint32_t Site) const { + return getValueSitesForKind(ValueKind)[Site].ValueData.size(); +} + +std::unique_ptr InstrProfRecord::getValueForSite( + uint32_t ValueKind, uint32_t Site) const { + uint32_t N = getNumValueDataForSite(ValueKind, Site); + if (N == 0) return std::unique_ptr(nullptr); + + std::unique_ptr VD(new InstrProfValueData[N]); + uint32_t I = 0; + for (auto V : getValueSitesForKind(ValueKind)[Site].ValueData) { + VD[I] = V; + I++; + } + assert(I == N); + + return VD; +} + +void InstrProfRecord::addValueData(uint32_t ValueKind, uint32_t Site, + InstrProfValueData *VData, uint32_t N, + ValueMapType *HashKeys) { + for (uint32_t I = 0; I < N; I++) { + VData[I].Value = remapValue(VData[I].Value, ValueKind, HashKeys); + } + std::vector &ValueSites = + getValueSitesForKind(ValueKind); + if (N == 0) + ValueSites.push_back(InstrProfValueSiteRecord()); + else + ValueSites.emplace_back(VData, VData + N); +} + +void InstrProfRecord::reserveSites(uint32_t ValueKind, uint32_t NumValueSites) { + std::vector &ValueSites = + getValueSitesForKind(ValueKind); + ValueSites.reserve(NumValueSites); +} + +instrprof_error InstrProfRecord::mergeValueProfData(uint32_t ValueKind, + InstrProfRecord &Src) { + uint32_t ThisNumValueSites = getNumValueSites(ValueKind); + uint32_t OtherNumValueSites = Src.getNumValueSites(ValueKind); + if (ThisNumValueSites != OtherNumValueSites) + return instrprof_error::value_site_count_mismatch; + std::vector &ThisSiteRecords = + getValueSitesForKind(ValueKind); + std::vector &OtherSiteRecords = + Src.getValueSitesForKind(ValueKind); + for (uint32_t I = 0; I < ThisNumValueSites; I++) + ThisSiteRecords[I].mergeValueData(OtherSiteRecords[I]); + return instrprof_error::success; +} + +void InstrProfRecord::updateStrings(InstrProfStringTable *StrTab) { + if (!StrTab) return; + + Name = StrTab->insertString(Name); + for (auto &VSite : IndirectCallSites) + for (auto &VData : VSite.ValueData) + VData.Value = (uint64_t)StrTab->insertString((const char *)VData.Value); +} + namespace IndexedInstrProf { enum class HashT : uint32_t { MD5,