Index: include/llvm/ProfileData/InstrProf.h =================================================================== --- include/llvm/ProfileData/InstrProf.h +++ include/llvm/ProfileData/InstrProf.h @@ -249,9 +249,8 @@ /// Same as the above interface but using an ArrayRef, as well as \p Sum. void annotateValueSite(Module &M, Instruction &Inst, - ArrayRef VDs, - uint64_t Sum, InstrProfValueKind ValueKind, - uint32_t MaxMDCount); + ArrayRef VDs, uint64_t Sum, + InstrProfValueKind ValueKind, uint32_t MaxMDCount); /// Extract the value profile data from \p Inst which is annotated with /// value profile meta data. Return false if there is no value data annotated, @@ -592,166 +591,167 @@ struct InstrProfRecord { StringRef Name; uint64_t Hash; - std::vector Counts; - SoftInstrProfErrors SIPE; - - InstrProfRecord() = default; - InstrProfRecord(StringRef Name, uint64_t Hash, std::vector Counts) - : Name(Name), Hash(Hash), Counts(std::move(Counts)) {} - InstrProfRecord(InstrProfRecord &&) = default; - InstrProfRecord(const InstrProfRecord &RHS) - : Name(RHS.Name), Hash(RHS.Hash), Counts(RHS.Counts), SIPE(RHS.SIPE), - ValueData(RHS.ValueData - ? llvm::make_unique(*RHS.ValueData) - : nullptr) {} - InstrProfRecord &operator=(InstrProfRecord &&) = default; - InstrProfRecord &operator=(const InstrProfRecord &RHS) { - Name = RHS.Name; - Hash = RHS.Hash; - Counts = RHS.Counts; - SIPE = RHS.SIPE; - if (!RHS.ValueData) { - ValueData = nullptr; + struct ValueProfData { + std::vector IndirectCallSites; + std::vector MemOPSizes; + }; + struct CounterHolder { + std::vector Counts; + std::unique_ptr ValueData; + SoftInstrProfErrors SIPE; + CounterHolder() = default; + CounterHolder(std::vector Counts) : Counts(std::move(Counts)) {} + CounterHolder(CounterHolder &&) = default; + CounterHolder(const CounterHolder &RHS) + : Counts(RHS.Counts), + ValueData(RHS.ValueData + ? llvm::make_unique(*RHS.ValueData) + : nullptr) {} + CounterHolder &operator=(CounterHolder &&) = default; + CounterHolder &operator=(const CounterHolder &RHS) { + Counts = RHS.Counts; + if (!RHS.ValueData) { + ValueData = nullptr; + return *this; + } + if (!ValueData) + ValueData = llvm::make_unique(*RHS.ValueData); + else + *ValueData = *RHS.ValueData; return *this; } - if (!ValueData) - ValueData = llvm::make_unique(*RHS.ValueData); - else - *ValueData = *RHS.ValueData; - return *this; - } - - using ValueMapType = std::vector>; - - /// 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; - - /// Return the array of profiled values at \p Site. If \p TotalC - /// is not null, the total count of all target values at this site - /// will be stored in \c *TotalC. - inline std::unique_ptr - getValueForSite(uint32_t ValueKind, uint32_t Site, - uint64_t *TotalC = nullptr) const; - - /// Get the target value/counts of kind \p ValueKind collected at site - /// \p Site and store the result in array \p Dest. Return the total - /// counts of all target values at this site. - inline uint64_t getValueForSite(InstrProfValueData Dest[], 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. - void addValueData(uint32_t ValueKind, uint32_t Site, - InstrProfValueData *VData, uint32_t N, - ValueMapType *ValueMap); - - /// Merge the counts in \p Other into this one. - /// Optionally scale merged counts by \p Weight. - void merge(InstrProfRecord &Other, uint64_t Weight = 1); - /// Scale up profile counts (including value profile data) by - /// \p Weight. - void scale(uint64_t Weight); - - /// Sort value profile data (per site) by count. - void sortValueData() { - for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) - for (auto &SR : getValueSitesForKind(Kind)) - SR.sortByCount(); - } - - /// Clear value data entries and edge counters. - void Clear() { - Counts.clear(); - clearValueData(); - } - - /// Clear value data entries - void clearValueData() { ValueData = nullptr; } + MutableArrayRef + getValueSitesForKind(uint32_t ValueKind) { + // Cast to /add/ const (should be an implicit_cast, ideally, if that's + // ever implemented in LLVM) to call the const overload of this function, + // then cast away the constness from the result. + auto AR = const_cast(this)->getValueSitesForKind( + ValueKind); + return makeMutableArrayRef( + const_cast(AR.data()), AR.size()); + } + ArrayRef + getValueSitesForKind(uint32_t ValueKind) const { + if (!ValueData) + return None; + switch (ValueKind) { + case IPVK_IndirectCallTarget: + return ValueData->IndirectCallSites; + case IPVK_MemOPSize: + return ValueData->MemOPSizes; + default: + llvm_unreachable("Unknown value kind!"); + } + } - /// Get the error contained within the record's soft error counter. - Error takeError() { return SIPE.takeError(); } + std::vector & + getOrCreateValueSitesForKind(uint32_t ValueKind) { + if (!ValueData) + ValueData = llvm::make_unique(); + switch (ValueKind) { + case IPVK_IndirectCallTarget: + return ValueData->IndirectCallSites; + case IPVK_MemOPSize: + return ValueData->MemOPSizes; + default: + llvm_unreachable("Unknown value kind!"); + } + } -private: - struct ValueProfData { - std::vector IndirectCallSites; - std::vector MemOPSizes; - }; - std::unique_ptr ValueData; - - MutableArrayRef - getValueSitesForKind(uint32_t ValueKind) { - // Cast to /add/ const (should be an implicit_cast, ideally, if that's ever - // implemented in LLVM) to call the const overload of this function, then - // cast away the constness from the result. - auto AR = const_cast(this)->getValueSitesForKind( - ValueKind); - return makeMutableArrayRef( - const_cast(AR.data()), AR.size()); - } - ArrayRef - getValueSitesForKind(uint32_t ValueKind) const { - if (!ValueData) - return None; - switch (ValueKind) { - case IPVK_IndirectCallTarget: - return ValueData->IndirectCallSites; - case IPVK_MemOPSize: - return ValueData->MemOPSizes; - default: - llvm_unreachable("Unknown value kind!"); + using ValueMapType = std::vector>; + + // Map indirect call target name hash to name string. + uint64_t remapValue(uint64_t Value, uint32_t ValueKind, + ValueMapType *HashKeys); + + // Merge Value Profile data from Src record to this record for ValueKind. + // Scale merged value counts by \p Weight. + void mergeValueProfData(uint32_t ValueKind, CounterHolder &Src, + uint64_t Weight); + + // Scale up value profile data count. + void scaleValueProfData(uint32_t ValueKind, uint64_t Weight); + + /// 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; + + /// Return the array of profiled values at \p Site. If \p TotalC + /// is not null, the total count of all target values at this site + /// will be stored in \c *TotalC. + inline std::unique_ptr + getValueForSite(uint32_t ValueKind, uint32_t Site, + uint64_t *TotalC = nullptr) const; + + /// Get the target value/counts of kind \p ValueKind collected at site + /// \p Site and store the result in array \p Dest. Return the total + /// counts of all target values at this site. + inline uint64_t getValueForSite(InstrProfValueData Dest[], + 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. + void addValueData(uint32_t ValueKind, uint32_t Site, + InstrProfValueData *VData, uint32_t N, + ValueMapType *ValueMap); + + /// Merge the counts in \p Other into this one. + /// Optionally scale merged counts by \p Weight. + void merge(CounterHolder &Other, uint64_t Weight = 1); + + /// Scale up profile counts (including value profile data) by + /// \p Weight. + void scale(uint64_t Weight); + + /// Sort value profile data (per site) by count. + void sortValueData() { + for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) + for (auto &SR : getValueSitesForKind(Kind)) + SR.sortByCount(); } - } - std::vector & - getOrCreateValueSitesForKind(uint32_t ValueKind) { - if (!ValueData) - ValueData = llvm::make_unique(); - switch (ValueKind) { - case IPVK_IndirectCallTarget: - return ValueData->IndirectCallSites; - case IPVK_MemOPSize: - return ValueData->MemOPSizes; - default: - llvm_unreachable("Unknown value kind!"); + /// Clear value data entries and edge counters. + void Clear() { + Counts.clear(); + clearValueData(); } - } - // Map indirect call target name hash to name string. - uint64_t remapValue(uint64_t Value, uint32_t ValueKind, - ValueMapType *HashKeys); + /// Clear value data entries + void clearValueData() { ValueData = nullptr; } - // Merge Value Profile data from Src record to this record for ValueKind. - // Scale merged value counts by \p Weight. - void mergeValueProfData(uint32_t ValueKind, InstrProfRecord &Src, - uint64_t Weight); + /// Get the error contained within the record's soft error counter. + Error takeError() { return SIPE.takeError(); } + }; + CounterHolder Counters; - // Scale up value profile data count. - void scaleValueProfData(uint32_t ValueKind, uint64_t Weight); + InstrProfRecord() = default; + InstrProfRecord(StringRef Name, uint64_t Hash, std::vector Counts) + : Name(Name), Hash(Hash), Counters(std::move(Counts)) {} }; -uint32_t InstrProfRecord::getNumValueKinds() const { +uint32_t InstrProfRecord::CounterHolder::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::getNumValueData(uint32_t ValueKind) const { +uint32_t +InstrProfRecord::CounterHolder::getNumValueData(uint32_t ValueKind) const { uint32_t N = 0; const std::vector &SiteRecords = getValueSitesForKind(ValueKind); @@ -761,18 +761,21 @@ return N; } -uint32_t InstrProfRecord::getNumValueSites(uint32_t ValueKind) const { +uint32_t +InstrProfRecord::CounterHolder::getNumValueSites(uint32_t ValueKind) const { return getValueSitesForKind(ValueKind).size(); } -uint32_t InstrProfRecord::getNumValueDataForSite(uint32_t ValueKind, - uint32_t Site) const { +uint32_t +InstrProfRecord::CounterHolder::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, - uint64_t *TotalC) const { +InstrProfRecord::CounterHolder::getValueForSite(uint32_t ValueKind, + uint32_t Site, + uint64_t *TotalC) const { uint64_t Dummy; uint64_t &TotalCount = (TotalC == nullptr ? Dummy : *TotalC); uint32_t N = getNumValueDataForSite(ValueKind, Site); @@ -787,9 +790,8 @@ return VD; } -uint64_t InstrProfRecord::getValueForSite(InstrProfValueData Dest[], - uint32_t ValueKind, - uint32_t Site) const { +uint64_t InstrProfRecord::CounterHolder::getValueForSite( + InstrProfValueData Dest[], uint32_t ValueKind, uint32_t Site) const { uint32_t I = 0; uint64_t TotalCount = 0; for (auto V : getValueSitesForKind(ValueKind)[Site].ValueData) { @@ -801,7 +803,8 @@ return TotalCount; } -void InstrProfRecord::reserveSites(uint32_t ValueKind, uint32_t NumValueSites) { +void InstrProfRecord::CounterHolder::reserveSites(uint32_t ValueKind, + uint32_t NumValueSites) { if (!NumValueSites) return; getOrCreateValueSitesForKind(ValueKind).reserve(NumValueSites); Index: include/llvm/ProfileData/InstrProfData.inc =================================================================== --- include/llvm/ProfileData/InstrProfData.inc +++ include/llvm/ProfileData/InstrProfData.inc @@ -314,8 +314,8 @@ /*! * \brief Read data from this record and save it to Record. */ - void deserializeTo(InstrProfRecord &Record, - InstrProfRecord::ValueMapType *VMap); + void deserializeTo(InstrProfRecord::CounterHolder &Record, + InstrProfRecord::CounterHolder::ValueMapType *VMap); /* * In-place byte swap: * Do byte swap for this instance. \c Old is the original order before @@ -358,12 +358,12 @@ * Return the total size in bytes of the on-disk value profile data * given the data stored in Record. */ - static uint32_t getSize(const InstrProfRecord &Record); + static uint32_t getSize(const InstrProfRecord::CounterHolder &Counters); /*! * Return a pointer to \c ValueProfData instance ready to be streamed. */ static std::unique_ptr - serializeFrom(const InstrProfRecord &Record); + serializeFrom(const InstrProfRecord::CounterHolder &Counters); /*! * Check the integrity of the record. */ @@ -392,8 +392,8 @@ /*! * Read data from this data and save it to \c Record. */ - void deserializeTo(InstrProfRecord &Record, - InstrProfRecord::ValueMapType *VMap); + void deserializeTo(InstrProfRecord::CounterHolder &Counters, + InstrProfRecord::CounterHolder::ValueMapType *VMap); void operator delete(void *ptr) { ::operator delete(ptr); } #endif } ValueProfData; @@ -412,8 +412,7 @@ * For documentation of the member methods below, refer to corresponding methods * in class InstrProfRecord. */ -typedef struct ValueProfRecordClosure { - const void *Record; +typedef struct ValueProfRecordVTable { uint32_t (*GetNumValueKinds)(const void *Record); uint32_t (*GetNumValueSites)(const void *Record, uint32_t VKind); uint32_t (*GetNumValueData)(const void *Record, uint32_t VKind); @@ -428,7 +427,7 @@ void (*GetValueForSite)(const void *R, InstrProfValueData *Dst, uint32_t K, uint32_t S); ValueProfData *(*AllocValueProfData)(size_t TotalSizeInBytes); -} ValueProfRecordClosure; +} ValueProfRecordVTable; INSTR_PROF_VISIBILITY ValueProfRecord * getFirstValueProfRecord(ValueProfData *VPD); @@ -528,17 +527,16 @@ * given the data stored in Record. */ INSTR_PROF_VISIBILITY uint32_t -getValueProfDataSize(ValueProfRecordClosure *Closure) { +getValueProfDataSize(const void *Record, const ValueProfRecordVTable *VTable) { uint32_t Kind; uint32_t TotalSize = sizeof(ValueProfData); - const void *Record = Closure->Record; for (Kind = IPVK_First; Kind <= IPVK_Last; Kind++) { - uint32_t NumValueSites = Closure->GetNumValueSites(Record, Kind); + uint32_t NumValueSites = VTable->GetNumValueSites(Record, Kind); if (!NumValueSites) continue; TotalSize += getValueProfRecordSize(NumValueSites, - Closure->GetNumValueData(Record, Kind)); + VTable->GetNumValueData(Record, Kind)); } return TotalSize; } @@ -548,19 +546,18 @@ * from the \c Closure and serialize the data into \c This record instance. */ INSTR_PROF_VISIBILITY void -serializeValueProfRecordFrom(ValueProfRecord *This, - ValueProfRecordClosure *Closure, - uint32_t ValueKind, uint32_t NumValueSites) { +serializeValueProfRecordFrom(ValueProfRecord *This, const void *Record, + const ValueProfRecordVTable *VTable, uint32_t ValueKind, + uint32_t NumValueSites) { uint32_t S; - const void *Record = Closure->Record; This->Kind = ValueKind; This->NumValueSites = NumValueSites; InstrProfValueData *DstVD = getValueProfRecordValueData(This); for (S = 0; S < NumValueSites; S++) { - uint32_t ND = Closure->GetNumValueDataForSite(Record, ValueKind, S); + uint32_t ND = VTable->GetNumValueDataForSite(Record, ValueKind, S); This->SiteCountArray[S] = ND; - Closure->GetValueForSite(Record, DstVD, ValueKind, S); + VTable->GetValueForSite(Record, DstVD, ValueKind, S); DstVD += ND; } } @@ -573,23 +570,23 @@ * in DstData. */ INSTR_PROF_VISIBILITY ValueProfData * -serializeValueProfDataFrom(ValueProfRecordClosure *Closure, +serializeValueProfDataFrom(const void *Record, const ValueProfRecordVTable *VTable, ValueProfData *DstData) { uint32_t Kind; uint32_t TotalSize = - DstData ? DstData->TotalSize : getValueProfDataSize(Closure); + DstData ? DstData->TotalSize : getValueProfDataSize(Record, VTable); ValueProfData *VPD = - DstData ? DstData : Closure->AllocValueProfData(TotalSize); + DstData ? DstData : VTable->AllocValueProfData(TotalSize); VPD->TotalSize = TotalSize; - VPD->NumValueKinds = Closure->GetNumValueKinds(Closure->Record); + VPD->NumValueKinds = VTable->GetNumValueKinds(Record); ValueProfRecord *VR = getFirstValueProfRecord(VPD); for (Kind = IPVK_First; Kind <= IPVK_Last; Kind++) { - uint32_t NumValueSites = Closure->GetNumValueSites(Closure->Record, Kind); + uint32_t NumValueSites = VTable->GetNumValueSites(Record, Kind); if (!NumValueSites) continue; - serializeValueProfRecordFrom(VR, Closure, Kind, NumValueSites); + serializeValueProfRecordFrom(VR, Record, VTable, Kind, NumValueSites); VR = getValueProfRecordNext(VR); } return VPD; Index: include/llvm/ProfileData/InstrProfReader.h =================================================================== --- include/llvm/ProfileData/InstrProfReader.h +++ include/llvm/ProfileData/InstrProfReader.h @@ -144,7 +144,7 @@ line_iterator Line; bool IsIRLevelProfile = false; - Error readValueProfileData(InstrProfRecord &Record); + Error readValueProfileData(InstrProfRecord::CounterHolder &Counters); public: TextInstrProfReader(std::unique_ptr DataBuffer_) @@ -199,7 +199,7 @@ uint32_t ValueKindLast; uint32_t CurValueDataSize; - InstrProfRecord::ValueMapType FunctionPtrToNameMap; + InstrProfRecord::CounterHolder::ValueMapType FunctionPtrToNameMap; public: RawInstrProfReader(std::unique_ptr DataBuffer) @@ -245,8 +245,8 @@ Error readName(InstrProfRecord &Record); Error readFuncHash(InstrProfRecord &Record); - Error readRawCounts(InstrProfRecord &Record); - Error readValueProfilingData(InstrProfRecord &Record); + Error readRawCounts(InstrProfRecord::CounterHolder &Counters); + Error readValueProfilingData(InstrProfRecord::CounterHolder &Counters); bool atEnd() const { return Data == DataEnd; } void advanceData() { Index: include/llvm/ProfileData/InstrProfWriter.h =================================================================== --- include/llvm/ProfileData/InstrProfWriter.h +++ include/llvm/ProfileData/InstrProfWriter.h @@ -33,7 +33,8 @@ class InstrProfWriter { public: - using ProfilingData = SmallDenseMap; + using ProfilingData = + SmallDenseMap; enum ProfKind { PF_Unknown = 0, PF_FE, PF_IRLevel }; private: @@ -62,7 +63,8 @@ Error writeText(raw_fd_ostream &OS); /// Write \c Record in text format to \c OS - static void writeRecordInText(const InstrProfRecord &Record, + static void writeRecordInText(StringRef Name, uint64_t Hash, + const InstrProfRecord::CounterHolder &Counters, InstrProfSymtab &Symtab, raw_fd_ostream &OS); /// Write the profile, returning the raw data. For testing. Index: include/llvm/ProfileData/ProfileCommon.h =================================================================== --- include/llvm/ProfileData/ProfileCommon.h +++ include/llvm/ProfileData/ProfileCommon.h @@ -17,6 +17,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/IR/ProfileSummary.h" +#include "llvm/ProfileData/InstrProf.h" #include "llvm/Support/Error.h" #include #include @@ -76,7 +77,7 @@ InstrProfSummaryBuilder(std::vector Cutoffs) : ProfileSummaryBuilder(std::move(Cutoffs)) {} - void addRecord(const InstrProfRecord &); + void addRecord(const InstrProfRecord::CounterHolder &); std::unique_ptr getSummary(); }; Index: lib/ProfileData/InstrProf.cpp =================================================================== --- lib/ProfileData/InstrProf.cpp +++ lib/ProfileData/InstrProf.cpp @@ -495,9 +495,9 @@ // Merge Value Profile data from Src record to this record for ValueKind. // Scale merged value counts by \p Weight. -void InstrProfRecord::mergeValueProfData(uint32_t ValueKind, - InstrProfRecord &Src, - uint64_t Weight) { +void InstrProfRecord::CounterHolder::mergeValueProfData(uint32_t ValueKind, + CounterHolder &Src, + uint64_t Weight) { uint32_t ThisNumValueSites = getNumValueSites(ValueKind); uint32_t OtherNumValueSites = Src.getNumValueSites(ValueKind); if (ThisNumValueSites != OtherNumValueSites) { @@ -514,7 +514,8 @@ ThisSiteRecords[I].merge(SIPE, OtherSiteRecords[I], Weight); } -void InstrProfRecord::merge(InstrProfRecord &Other, uint64_t Weight) { +void InstrProfRecord::CounterHolder::merge(CounterHolder &Other, + uint64_t Weight) { // If the number of counters doesn't match we either have bad data // or a hash collision. if (Counts.size() != Other.Counts.size()) { @@ -534,12 +535,14 @@ mergeValueProfData(Kind, Other, Weight); } -void InstrProfRecord::scaleValueProfData(uint32_t ValueKind, uint64_t Weight) { +void InstrProfRecord::CounterHolder::scaleValueProfData(uint32_t ValueKind, + uint64_t Weight) { + SoftInstrProfErrors SIPE; for (auto &R : getValueSitesForKind(ValueKind)) R.scale(SIPE, Weight); } -void InstrProfRecord::scale(uint64_t Weight) { +void InstrProfRecord::CounterHolder::scale(uint64_t Weight) { for (auto &Count : this->Counts) { bool Overflowed; Count = SaturatingMultiply(Count, Weight, &Overflowed); @@ -551,8 +554,9 @@ } // Map indirect call target name hash to name string. -uint64_t InstrProfRecord::remapValue(uint64_t Value, uint32_t ValueKind, - ValueMapType *ValueMap) { +uint64_t InstrProfRecord::CounterHolder::remapValue(uint64_t Value, + uint32_t ValueKind, + ValueMapType *ValueMap) { if (!ValueMap) return Value; switch (ValueKind) { @@ -575,9 +579,11 @@ return Value; } -void InstrProfRecord::addValueData(uint32_t ValueKind, uint32_t Site, - InstrProfValueData *VData, uint32_t N, - ValueMapType *ValueMap) { +void InstrProfRecord::CounterHolder::addValueData(uint32_t ValueKind, + uint32_t Site, + InstrProfValueData *VData, + uint32_t N, + ValueMapType *ValueMap) { for (uint32_t I = 0; I < N; I++) { VData[I].Value = remapValue(VData[I].Value, ValueKind, ValueMap); } @@ -593,77 +599,77 @@ #include "llvm/ProfileData/InstrProfData.inc" /*! - * \brief ValueProfRecordClosure Interface implementation for InstrProfRecord - * class. These C wrappers are used as adaptors so that C++ code can be - * invoked as callbacks. + * \brief ValueProfRecordClosure Interface implementation for + * InstrProfRecord::CounterHolder class. These C wrappers are used as adaptors + * so that C++ code can be invoked as callbacks. */ -uint32_t getNumValueKindsInstrProf(const void *Record) { - return reinterpret_cast(Record)->getNumValueKinds(); +uint32_t getNumValueKindsInstrProfCounters(const void *Record) { + return reinterpret_cast(Record) + ->getNumValueKinds(); } -uint32_t getNumValueSitesInstrProf(const void *Record, uint32_t VKind) { - return reinterpret_cast(Record) +uint32_t getNumValueSitesInstrProfCounters(const void *Record, uint32_t VKind) { + return reinterpret_cast(Record) ->getNumValueSites(VKind); } -uint32_t getNumValueDataInstrProf(const void *Record, uint32_t VKind) { - return reinterpret_cast(Record) +uint32_t getNumValueDataInstrProfCounters(const void *Record, uint32_t VKind) { + return reinterpret_cast(Record) ->getNumValueData(VKind); } -uint32_t getNumValueDataForSiteInstrProf(const void *R, uint32_t VK, - uint32_t S) { - return reinterpret_cast(R) +uint32_t getNumValueDataForSiteInstrProfCounters(const void *R, uint32_t VK, + uint32_t S) { + return reinterpret_cast(R) ->getNumValueDataForSite(VK, S); } -void getValueForSiteInstrProf(const void *R, InstrProfValueData *Dst, - uint32_t K, uint32_t S) { - reinterpret_cast(R)->getValueForSite(Dst, K, S); +void getValueForSiteInstrProfCounters(const void *R, InstrProfValueData *Dst, + uint32_t K, uint32_t S) { + reinterpret_cast(R)->getValueForSite( + Dst, K, S); } -ValueProfData *allocValueProfDataInstrProf(size_t TotalSizeInBytes) { +ValueProfData *allocValueProfDataInstrProfCounters(size_t TotalSizeInBytes) { ValueProfData *VD = (ValueProfData *)(new (::operator new(TotalSizeInBytes)) ValueProfData()); memset(VD, 0, TotalSizeInBytes); return VD; } -static ValueProfRecordClosure InstrProfRecordClosure = { +static const ValueProfRecordVTable InstrProfRecordCountersVTable = { + getNumValueKindsInstrProfCounters, + getNumValueSitesInstrProfCounters, + getNumValueDataInstrProfCounters, + getNumValueDataForSiteInstrProfCounters, nullptr, - getNumValueKindsInstrProf, - getNumValueSitesInstrProf, - getNumValueDataInstrProf, - getNumValueDataForSiteInstrProf, - nullptr, - getValueForSiteInstrProf, - allocValueProfDataInstrProf}; + getValueForSiteInstrProfCounters, + allocValueProfDataInstrProfCounters}; // Wrapper implementation using the closure mechanism. -uint32_t ValueProfData::getSize(const InstrProfRecord &Record) { - auto Closure = InstrProfRecordClosure; - Closure.Record = &Record; - return getValueProfDataSize(&Closure); +uint32_t +ValueProfData::getSize(const InstrProfRecord::CounterHolder &Counters) { + return getValueProfDataSize(&Counters, &InstrProfRecordCountersVTable); } // Wrapper implementation using the closure mechanism. std::unique_ptr -ValueProfData::serializeFrom(const InstrProfRecord &Record) { - InstrProfRecordClosure.Record = &Record; +ValueProfData::serializeFrom(const InstrProfRecord::CounterHolder &Counters) { - std::unique_ptr VPD( - serializeValueProfDataFrom(&InstrProfRecordClosure, nullptr)); + std::unique_ptr VPD(serializeValueProfDataFrom( + &Counters, &InstrProfRecordCountersVTable, nullptr)); return VPD; } -void ValueProfRecord::deserializeTo(InstrProfRecord &Record, - InstrProfRecord::ValueMapType *VMap) { - Record.reserveSites(Kind, NumValueSites); +void ValueProfRecord::deserializeTo( + InstrProfRecord::CounterHolder &Counters, + InstrProfRecord::CounterHolder::ValueMapType *VMap) { + Counters.reserveSites(Kind, NumValueSites); InstrProfValueData *ValueData = getValueProfRecordValueData(this); for (uint64_t VSite = 0; VSite < NumValueSites; ++VSite) { uint8_t ValueDataCount = this->SiteCountArray[VSite]; - Record.addValueData(Kind, VSite, ValueData, ValueDataCount, VMap); + Counters.addValueData(Kind, VSite, ValueData, ValueDataCount, VMap); ValueData += ValueDataCount; } } @@ -696,14 +702,15 @@ } } -void ValueProfData::deserializeTo(InstrProfRecord &Record, - InstrProfRecord::ValueMapType *VMap) { +void ValueProfData::deserializeTo( + InstrProfRecord::CounterHolder &Counters, + InstrProfRecord::CounterHolder::ValueMapType *VMap) { if (NumValueKinds == 0) return; ValueProfRecord *VR = getFirstValueProfRecord(this); for (uint32_t K = 0; K < NumValueKinds; K++) { - VR->deserializeTo(Record, VMap); + VR->deserializeTo(Counters, VMap); VR = getValueProfRecordNext(VR); } } @@ -803,13 +810,13 @@ const InstrProfRecord &InstrProfR, InstrProfValueKind ValueKind, uint32_t SiteIdx, uint32_t MaxMDCount) { - uint32_t NV = InstrProfR.getNumValueDataForSite(ValueKind, SiteIdx); + uint32_t NV = InstrProfR.Counters.getNumValueDataForSite(ValueKind, SiteIdx); if (!NV) return; uint64_t Sum = 0; std::unique_ptr VD = - InstrProfR.getValueForSite(ValueKind, SiteIdx, &Sum); + InstrProfR.Counters.getValueForSite(ValueKind, SiteIdx, &Sum); ArrayRef VDs(VD.get(), NV); annotateValueSite(M, Inst, VDs, Sum, ValueKind, MaxMDCount); Index: lib/ProfileData/InstrProfReader.cpp =================================================================== --- lib/ProfileData/InstrProfReader.cpp +++ lib/ProfileData/InstrProfReader.cpp @@ -155,8 +155,8 @@ return success(); } -Error -TextInstrProfReader::readValueProfileData(InstrProfRecord &Record) { +Error TextInstrProfReader::readValueProfileData( + InstrProfRecord::CounterHolder &Counters) { #define CHECK_LINE_END(Line) \ if (Line.is_at_end()) \ @@ -190,7 +190,7 @@ if (!NumValueSites) continue; - Record.reserveSites(VK, NumValueSites); + Counters.reserveSites(VK, NumValueSites); for (uint32_t S = 0; S < NumValueSites; S++) { VP_READ_ADVANCE(NumValueData); @@ -210,8 +210,8 @@ CurrentValues.push_back({Value, TakenCount}); Line++; } - Record.addValueData(ValueKind, S, CurrentValues.data(), NumValueData, - nullptr); + Counters.addValueData(ValueKind, S, CurrentValues.data(), NumValueData, + nullptr); } } return success(); @@ -252,19 +252,19 @@ return error(instrprof_error::malformed); // Read each counter and fill our internal storage with the values. - Record.Clear(); - Record.Counts.reserve(NumCounters); + Record.Counters.Clear(); + Record.Counters.Counts.reserve(NumCounters); for (uint64_t I = 0; I < NumCounters; ++I) { if (Line.is_at_end()) return error(instrprof_error::truncated); uint64_t Count; if ((Line++)->getAsInteger(10, Count)) return error(instrprof_error::malformed); - Record.Counts.push_back(Count); + Record.Counters.Counts.push_back(Count); } // Check if value profile data exists and read it if so. - if (Error E = readValueProfileData(Record)) + if (Error E = readValueProfileData(Record.Counters)) return E; // This is needed to avoid two pass parsing because llvm-profdata @@ -390,7 +390,7 @@ template Error RawInstrProfReader::readRawCounts( - InstrProfRecord &Record) { + InstrProfRecord::CounterHolder &Counters) { uint32_t NumCounters = swap(Data->NumCounters); IntPtrT CounterPtr = Data->CounterPtr; if (NumCounters == 0) @@ -405,20 +405,20 @@ return error(instrprof_error::malformed); if (ShouldSwapBytes) { - Record.Counts.clear(); - Record.Counts.reserve(RawCounts.size()); + Counters.Counts.clear(); + Counters.Counts.reserve(RawCounts.size()); for (uint64_t Count : RawCounts) - Record.Counts.push_back(swap(Count)); + Counters.Counts.push_back(swap(Count)); } else - Record.Counts = RawCounts; + Counters.Counts = RawCounts; return success(); } template Error RawInstrProfReader::readValueProfilingData( - InstrProfRecord &Record) { - Record.clearValueData(); + InstrProfRecord::CounterHolder &Counters) { + Counters.clearValueData(); CurValueDataSize = 0; // Need to match the logic in value profile dumper code in compiler-rt: uint32_t NumValueKinds = 0; @@ -439,7 +439,7 @@ // Note that besides deserialization, this also performs the conversion for // indirect call targets. The function pointers from the raw profile are // remapped into function name hashes. - VDataPtrOrErr.get()->deserializeTo(Record, &Symtab->getAddrHashMap()); + VDataPtrOrErr.get()->deserializeTo(Counters, &Symtab->getAddrHashMap()); CurValueDataSize = VDataPtrOrErr.get()->getSize(); return success(); } @@ -460,11 +460,11 @@ return E; // Read raw counts and set Record. - if (Error E = readRawCounts(Record)) + if (Error E = readRawCounts(Record.Counters)) return E; // Read value data and set Record. - if (Error E = readValueProfilingData(Record)) + if (Error E = readValueProfilingData(Record.Counters)) return E; // Iterate. @@ -495,7 +495,7 @@ if (VDataPtrOrErr.takeError()) return false; - VDataPtrOrErr.get()->deserializeTo(DataBuffer.back(), nullptr); + VDataPtrOrErr.get()->deserializeTo(DataBuffer.back().Counters, nullptr); D += VDataPtrOrErr.get()->TotalSize; return true; @@ -728,7 +728,7 @@ if (Error E = Record.takeError()) return error(std::move(E)); - Counts = Record.get().Counts; + Counts = Record.get().Counters.Counts; return success(); } Index: lib/ProfileData/InstrProfWriter.cpp =================================================================== --- lib/ProfileData/InstrProfWriter.cpp +++ lib/ProfileData/InstrProfWriter.cpp @@ -119,13 +119,13 @@ offset_type M = 0; for (const auto &ProfileData : *V) { - const InstrProfRecord &ProfRecord = ProfileData.second; + const InstrProfRecord::CounterHolder &Counters = ProfileData.second; M += sizeof(uint64_t); // The function hash M += sizeof(uint64_t); // The size of the Counts vector - M += ProfRecord.Counts.size() * sizeof(uint64_t); + M += Counters.Counts.size() * sizeof(uint64_t); // Value data - M += ValueProfData::getSize(ProfileData.second); + M += ValueProfData::getSize(Counters); } LE.write(M); @@ -136,22 +136,23 @@ Out.write(K.data(), N); } - void EmitData(raw_ostream &Out, key_type_ref, data_type_ref V, offset_type) { + void EmitData(raw_ostream &Out, key_type_ref K, data_type_ref V, + offset_type) { using namespace support; endian::Writer LE(Out); for (const auto &ProfileData : *V) { - const InstrProfRecord &ProfRecord = ProfileData.second; - SummaryBuilder->addRecord(ProfRecord); + const InstrProfRecord::CounterHolder &Counters = ProfileData.second; + SummaryBuilder->addRecord(ProfileData.second); LE.write(ProfileData.first); // Function hash - LE.write(ProfRecord.Counts.size()); - for (uint64_t I : ProfRecord.Counts) + LE.write(Counters.Counts.size()); + for (uint64_t I : Counters.Counts) LE.write(I); // Write value data std::unique_ptr VDataPtr = - ValueProfData::serializeFrom(ProfileData.second); + ValueProfData::serializeFrom(Counters); uint32_t S = VDataPtr->getSize(); VDataPtr->swapBytesFromHost(ValueProfDataEndianness); Out.write((const char *)VDataPtr.get(), S); @@ -181,20 +182,18 @@ bool NewFunc; ProfilingData::iterator Where; - std::tie(Where, NewFunc) = - ProfileDataMap.insert(std::make_pair(I.Hash, InstrProfRecord())); - InstrProfRecord &Dest = Where->second; + std::tie(Where, NewFunc) = ProfileDataMap.insert( + std::make_pair(I.Hash, InstrProfRecord::CounterHolder())); + InstrProfRecord::CounterHolder &Dest = Where->second; if (NewFunc) { // We've never seen a function with this name and hash, add it. - Dest = std::move(I); - // Fix up the name to avoid dangling reference. - Dest.Name = FunctionData.find(Dest.Name)->getKey(); + Dest = std::move(I.Counters); if (Weight > 1) Dest.scale(Weight); } else { // We're updating a function we've seen before. - Dest.merge(I, Weight); + Dest.merge(I.Counters, Weight); } Dest.sortValueData(); @@ -204,9 +203,14 @@ Error InstrProfWriter::mergeRecordsFromWriter(InstrProfWriter &&IPW) { for (auto &I : IPW.FunctionData) - for (auto &Func : I.getValue()) - if (Error E = addRecord(std::move(Func.second), 1)) + for (auto &Func : I.getValue()) { + InstrProfRecord R; + R.Name = I.getKey(); + R.Hash = Func.first; + R.Counters = std::move(Func.second); + if (Error E = addRecord(std::move(R), 1)) return E; + } return Error::success(); } @@ -214,8 +218,8 @@ if (!Sparse) return true; for (const auto &Func : PD) { - const InstrProfRecord &IPR = Func.second; - if (llvm::any_of(IPR.Counts, [](uint64_t Count) { return Count > 0; })) + const InstrProfRecord::CounterHolder &CH = Func.second; + if (llvm::any_of(CH.Counts, [](uint64_t Count) { return Count > 0; })) return true; } return false; @@ -323,33 +327,35 @@ #include "llvm/ProfileData/InstrProfData.inc" }; -void InstrProfWriter::writeRecordInText(const InstrProfRecord &Func, - InstrProfSymtab &Symtab, - raw_fd_ostream &OS) { - OS << Func.Name << "\n"; - OS << "# Func Hash:\n" << Func.Hash << "\n"; - OS << "# Num Counters:\n" << Func.Counts.size() << "\n"; +void InstrProfWriter::writeRecordInText( + StringRef Name, uint64_t Hash, + const InstrProfRecord::CounterHolder &Counters, InstrProfSymtab &Symtab, + raw_fd_ostream &OS) { + OS << Name << "\n"; + OS << "# Func Hash:\n" << Hash << "\n"; + OS << "# Num Counters:\n" << Counters.Counts.size() << "\n"; OS << "# Counter Values:\n"; - for (uint64_t Count : Func.Counts) + for (uint64_t Count : Counters.Counts) OS << Count << "\n"; - uint32_t NumValueKinds = Func.getNumValueKinds(); + uint32_t NumValueKinds = Counters.getNumValueKinds(); if (!NumValueKinds) { OS << "\n"; return; } - OS << "# Num Value Kinds:\n" << Func.getNumValueKinds() << "\n"; + OS << "# Num Value Kinds:\n" << Counters.getNumValueKinds() << "\n"; for (uint32_t VK = 0; VK < IPVK_Last + 1; VK++) { - uint32_t NS = Func.getNumValueSites(VK); + uint32_t NS = Counters.getNumValueSites(VK); if (!NS) continue; OS << "# ValueKind = " << ValueProfKindStr[VK] << ":\n" << VK << "\n"; OS << "# NumValueSites:\n" << NS << "\n"; for (uint32_t S = 0; S < NS; S++) { - uint32_t ND = Func.getNumValueDataForSite(VK, S); + uint32_t ND = Counters.getNumValueDataForSite(VK, S); OS << ND << "\n"; - std::unique_ptr VD = Func.getValueForSite(VK, S); + std::unique_ptr VD = + Counters.getValueForSite(VK, S); for (uint32_t I = 0; I < ND; I++) { if (VK == IPVK_IndirectCallTarget) OS << Symtab.getFuncName(VD[I].Value) << ":" << VD[I].Count << "\n"; @@ -375,6 +381,6 @@ for (const auto &I : FunctionData) if (shouldEncodeData(I.getValue())) for (const auto &Func : I.getValue()) - writeRecordInText(Func.second, Symtab, OS); + writeRecordInText(I.getKey(), Func.first, Func.second, Symtab, OS); return Error::success(); } Index: lib/ProfileData/ProfileSummaryBuilder.cpp =================================================================== --- lib/ProfileData/ProfileSummaryBuilder.cpp +++ lib/ProfileData/ProfileSummaryBuilder.cpp @@ -33,14 +33,15 @@ const ArrayRef ProfileSummaryBuilder::DefaultCutoffs = DefaultCutoffsData; -void InstrProfSummaryBuilder::addRecord(const InstrProfRecord &R) { +void InstrProfSummaryBuilder::addRecord( + const InstrProfRecord::CounterHolder &C) { // The first counter is not necessarily an entry count for IR // instrumentation profiles. // Eventually MaxFunctionCount will become obsolete and this can be // removed. - addEntryCount(R.Counts[0]); - for (size_t I = 1, E = R.Counts.size(); I < E; ++I) - addInternalCount(R.Counts[I]); + addEntryCount(C.Counts[0]); + for (auto C : drop_begin(C.Counts, 1)) + addInternalCount(C); } // To compute the detailed summary, we consider each line containing samples as Index: lib/Transforms/Instrumentation/PGOInstrumentation.cpp =================================================================== --- lib/Transforms/Instrumentation/PGOInstrumentation.cpp +++ lib/Transforms/Instrumentation/PGOInstrumentation.cpp @@ -961,7 +961,7 @@ return false; } ProfileRecord = std::move(Result.get()); - std::vector &CountFromProfile = ProfileRecord.Counts; + std::vector &CountFromProfile = ProfileRecord.Counters.Counts; NumOfPGOFunc++; DEBUG(dbgs() << CountFromProfile.size() << " counts\n"); @@ -1128,7 +1128,8 @@ } void SelectInstVisitor::annotateOneSelectInst(SelectInst &SI) { - std::vector &CountFromProfile = UseFunc->getProfileRecord().Counts; + std::vector &CountFromProfile = + UseFunc->getProfileRecord().Counters.Counts; assert(*CurCtrIdx < CountFromProfile.size() && "Out of bound access of counters"); uint64_t SCounts[2]; @@ -1220,7 +1221,7 @@ void PGOUseFunc::annotateValueSites(uint32_t Kind) { unsigned ValueSiteIndex = 0; auto &ValueSites = FuncInfo.ValueSites[Kind]; - unsigned NumValueSites = ProfileRecord.getNumValueSites(Kind); + unsigned NumValueSites = ProfileRecord.Counters.getNumValueSites(Kind); if (NumValueSites != ValueSites.size()) { auto &Ctx = M->getContext(); Ctx.diagnose(DiagnosticInfoPGOProfile( Index: tools/llvm-profdata/llvm-profdata.cpp =================================================================== --- tools/llvm-profdata/llvm-profdata.cpp +++ tools/llvm-profdata/llvm-profdata.cpp @@ -458,9 +458,9 @@ std::vector ValueSitesHistogram; } ValueSitesStats; -static void traverseAllValueSites(const InstrProfRecord &Func, uint32_t VK, - ValueSitesStats &Stats, raw_fd_ostream &OS, - InstrProfSymtab *Symtab) { +static void traverseAllValueSites(const InstrProfRecord::CounterHolder &Func, + uint32_t VK, ValueSitesStats &Stats, + raw_fd_ostream &OS, InstrProfSymtab *Symtab) { uint32_t NS = Func.getNumValueSites(VK); Stats.TotalNumValueSites += NS; for (size_t I = 0; I < NS; ++I) { @@ -528,12 +528,13 @@ if (doTextFormatDump) { InstrProfSymtab &Symtab = Reader->getSymtab(); - InstrProfWriter::writeRecordInText(Func, Symtab, OS); + InstrProfWriter::writeRecordInText(Func.Name, Func.Hash, Func.Counters, + Symtab, OS); continue; } - assert(Func.Counts.size() > 0 && "function missing entry counter"); - Builder.addRecord(Func); + assert(Func.Counters.Counts.size() > 0 && "function missing entry counter"); + Builder.addRecord(Func.Counters); if (Show) { @@ -544,15 +545,15 @@ OS << " " << Func.Name << ":\n" << " Hash: " << format("0x%016" PRIx64, Func.Hash) << "\n" - << " Counters: " << Func.Counts.size() << "\n"; + << " Counters: " << Func.Counters.Counts.size() << "\n"; if (!IsIRInstr) - OS << " Function count: " << Func.Counts[0] << "\n"; + OS << " Function count: " << Func.Counters.Counts[0] << "\n"; if (ShowIndirectCallTargets) OS << " Indirect Call Site Count: " - << Func.getNumValueSites(IPVK_IndirectCallTarget) << "\n"; + << Func.Counters.getNumValueSites(IPVK_IndirectCallTarget) << "\n"; - uint32_t NumMemOPCalls = Func.getNumValueSites(IPVK_MemOPSize); + uint32_t NumMemOPCalls = Func.Counters.getNumValueSites(IPVK_MemOPSize); if (ShowMemOPSizes && NumMemOPCalls > 0) OS << " Number of Memory Intrinsics Calls: " << NumMemOPCalls << "\n"; @@ -560,23 +561,23 @@ if (ShowCounts) { OS << " Block counts: ["; size_t Start = (IsIRInstr ? 0 : 1); - for (size_t I = Start, E = Func.Counts.size(); I < E; ++I) { - OS << (I == Start ? "" : ", ") << Func.Counts[I]; + for (size_t I = Start, E = Func.Counters.Counts.size(); I < E; ++I) { + OS << (I == Start ? "" : ", ") << Func.Counters.Counts[I]; } OS << "]\n"; } if (ShowIndirectCallTargets) { OS << " Indirect Target Results:\n"; - traverseAllValueSites(Func, IPVK_IndirectCallTarget, + traverseAllValueSites(Func.Counters, IPVK_IndirectCallTarget, VPStats[IPVK_IndirectCallTarget], OS, &(Reader->getSymtab())); } if (ShowMemOPSizes && NumMemOPCalls > 0) { OS << " Memory Intrinsic Size Results:\n"; - traverseAllValueSites(Func, IPVK_MemOPSize, VPStats[IPVK_MemOPSize], OS, - nullptr); + traverseAllValueSites(Func.Counters, IPVK_MemOPSize, + VPStats[IPVK_MemOPSize], OS, nullptr); } } } Index: unittests/ProfileData/InstrProfTest.cpp =================================================================== --- unittests/ProfileData/InstrProfTest.cpp +++ unittests/ProfileData/InstrProfTest.cpp @@ -79,11 +79,11 @@ ASSERT_TRUE(I != E); ASSERT_EQ(StringRef("foo"), I->Name); ASSERT_EQ(0x1234U, I->Hash); - ASSERT_EQ(4U, I->Counts.size()); - ASSERT_EQ(1U, I->Counts[0]); - ASSERT_EQ(2U, I->Counts[1]); - ASSERT_EQ(3U, I->Counts[2]); - ASSERT_EQ(4U, I->Counts[3]); + ASSERT_EQ(4U, I->Counters.Counts.size()); + ASSERT_EQ(1U, I->Counters.Counts[0]); + ASSERT_EQ(2U, I->Counters.Counts[1]); + ASSERT_EQ(3U, I->Counters.Counts[2]); + ASSERT_EQ(4U, I->Counters.Counts[3]); ASSERT_TRUE(++I == E); } @@ -97,15 +97,15 @@ Expected R = Reader->getInstrProfRecord("foo", 0x1234); ASSERT_TRUE(NoError(R.takeError())); - ASSERT_EQ(2U, R->Counts.size()); - ASSERT_EQ(1U, R->Counts[0]); - ASSERT_EQ(2U, R->Counts[1]); + ASSERT_EQ(2U, R->Counters.Counts.size()); + ASSERT_EQ(1U, R->Counters.Counts[0]); + ASSERT_EQ(2U, R->Counters.Counts[1]); R = Reader->getInstrProfRecord("foo", 0x1235); ASSERT_TRUE(NoError(R.takeError())); - ASSERT_EQ(2U, R->Counts.size()); - ASSERT_EQ(3U, R->Counts[0]); - ASSERT_EQ(4U, R->Counts[1]); + ASSERT_EQ(2U, R->Counters.Counts.size()); + ASSERT_EQ(3U, R->Counters.Counts[0]); + ASSERT_EQ(4U, R->Counters.Counts[1]); R = Reader->getInstrProfRecord("foo", 0x5678); ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, R.takeError())); @@ -217,14 +217,14 @@ Expected R = Reader->getInstrProfRecord("func1", 0x1234); ASSERT_TRUE(NoError(R.takeError())); - ASSERT_EQ(1U, R->Counts.size()); - ASSERT_EQ(42U, R->Counts[0]); + ASSERT_EQ(1U, R->Counters.Counts.size()); + ASSERT_EQ(42U, R->Counters.Counts[0]); R = Reader->getInstrProfRecord("func2", 0x1234); ASSERT_TRUE(NoError(R.takeError())); - ASSERT_EQ(2U, R->Counts.size()); - ASSERT_EQ(0U, R->Counts[0]); - ASSERT_EQ(0U, R->Counts[1]); + ASSERT_EQ(2U, R->Counters.Counts.size()); + ASSERT_EQ(0U, R->Counters.Counts[0]); + ASSERT_EQ(0U, R->Counters.Counts[1]); } static const char callee1[] = "callee1"; @@ -241,16 +241,17 @@ InstrProfRecord Record4("callee3", 0x1235, {3, 4}); // 4 value sites. - Record1.reserveSites(IPVK_IndirectCallTarget, 4); + Record1.Counters.reserveSites(IPVK_IndirectCallTarget, 4); InstrProfValueData VD0[] = { {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}}; - Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr); + Record1.Counters.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr); // No value profile data at the second site. - Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr); + Record1.Counters.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, + nullptr); InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}}; - Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr); + Record1.Counters.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr); InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}}; - Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr); + Record1.Counters.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr); NoError(Writer.addRecord(std::move(Record1))); NoError(Writer.addRecord(std::move(Record2))); @@ -261,15 +262,15 @@ Expected R = Reader->getInstrProfRecord("caller", 0x1234); ASSERT_TRUE(NoError(R.takeError())); - ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget)); - ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); - ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1)); - ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2)); - ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3)); + ASSERT_EQ(4U, R->Counters.getNumValueSites(IPVK_IndirectCallTarget)); + ASSERT_EQ(3U, R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); + ASSERT_EQ(0U, R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 1)); + ASSERT_EQ(2U, R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 2)); + ASSERT_EQ(1U, R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 3)); uint64_t TotalC; std::unique_ptr VD = - R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC); + R->Counters.getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC); ASSERT_EQ(3U, VD[0].Count); ASSERT_EQ(2U, VD[1].Count); @@ -283,10 +284,10 @@ TEST_P(MaybeSparseInstrProfTest, annotate_vp_data) { InstrProfRecord Record("caller", 0x1234, {1, 2}); - Record.reserveSites(IPVK_IndirectCallTarget, 1); + Record.Counters.reserveSites(IPVK_IndirectCallTarget, 1); InstrProfValueData VD0[] = {{1000, 1}, {2000, 2}, {3000, 3}, {5000, 5}, {4000, 4}, {6000, 6}}; - Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 6, nullptr); + Record.Counters.addValueData(IPVK_IndirectCallTarget, 0, VD0, 6, nullptr); NoError(Writer.addRecord(std::move(Record))); auto Profile = Writer.writeBuffer(); readProfile(std::move(Profile)); @@ -384,16 +385,17 @@ InstrProfRecord Record4("callee3", 0x1235, {3, 4}); // 4 value sites. - Record1.reserveSites(IPVK_IndirectCallTarget, 4); + Record1.Counters.reserveSites(IPVK_IndirectCallTarget, 4); InstrProfValueData VD0[] = { {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}}; - Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr); + Record1.Counters.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr); // No value profile data at the second site. - Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr); + Record1.Counters.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, + nullptr); InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}}; - Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr); + Record1.Counters.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr); InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}}; - Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr); + Record1.Counters.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr); NoError(Writer.addRecord(std::move(Record1), 10)); NoError(Writer.addRecord(std::move(Record2))); @@ -404,15 +406,15 @@ Expected R = Reader->getInstrProfRecord("caller", 0x1234); ASSERT_TRUE(NoError(R.takeError())); - ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget)); - ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); - ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1)); - ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2)); - ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3)); + ASSERT_EQ(4U, R->Counters.getNumValueSites(IPVK_IndirectCallTarget)); + ASSERT_EQ(3U, R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); + ASSERT_EQ(0U, R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 1)); + ASSERT_EQ(2U, R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 2)); + ASSERT_EQ(1U, R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 3)); uint64_t TotalC; std::unique_ptr VD = - R->getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC); + R->Counters.getValueForSite(IPVK_IndirectCallTarget, 0, &TotalC); ASSERT_EQ(30U, VD[0].Count); ASSERT_EQ(20U, VD[1].Count); ASSERT_EQ(10U, VD[2].Count); @@ -430,16 +432,17 @@ InstrProfRecord Record4("callee3", 0x1235, {3, 4}); // 4 value sites. - Record1.reserveSites(IPVK_IndirectCallTarget, 4); + Record1.Counters.reserveSites(IPVK_IndirectCallTarget, 4); InstrProfValueData VD0[] = { {(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}, {(uint64_t)callee3, 3}}; - Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr); + Record1.Counters.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr); // No value profile data at the second site. - Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr); + Record1.Counters.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, + nullptr); InstrProfValueData VD2[] = {{(uint64_t)callee1, 1}, {(uint64_t)callee2, 2}}; - Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr); + Record1.Counters.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr); InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}}; - Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr); + Record1.Counters.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr); NoError(Writer.addRecord(std::move(Record1))); NoError(Writer.addRecord(std::move(Record2))); @@ -457,14 +460,14 @@ Expected R = Reader->getInstrProfRecord("caller", 0x1234); ASSERT_TRUE(NoError(R.takeError())); - ASSERT_EQ(4U, R->getNumValueSites(IPVK_IndirectCallTarget)); - ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); - ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1)); - ASSERT_EQ(2U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2)); - ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3)); + ASSERT_EQ(4U, R->Counters.getNumValueSites(IPVK_IndirectCallTarget)); + ASSERT_EQ(3U, R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); + ASSERT_EQ(0U, R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 1)); + ASSERT_EQ(2U, R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 2)); + ASSERT_EQ(1U, R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 3)); std::unique_ptr VD = - R->getValueForSite(IPVK_IndirectCallTarget, 0); + R->Counters.getValueForSite(IPVK_IndirectCallTarget, 0); ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3")); ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2")); ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1")); @@ -484,46 +487,49 @@ InstrProfRecord Record6(callee4, 0x1235, {3, 5}); // 5 value sites. - Record11.reserveSites(IPVK_IndirectCallTarget, 5); + Record11.Counters.reserveSites(IPVK_IndirectCallTarget, 5); InstrProfValueData VD0[] = {{uint64_t(callee1), 1}, {uint64_t(callee2), 2}, {uint64_t(callee3), 3}, {uint64_t(callee4), 4}}; - Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 4, nullptr); + Record11.Counters.addValueData(IPVK_IndirectCallTarget, 0, VD0, 4, nullptr); // No value profile data at the second site. - Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr); + Record11.Counters.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, + nullptr); InstrProfValueData VD2[] = { {uint64_t(callee1), 1}, {uint64_t(callee2), 2}, {uint64_t(callee3), 3}}; - Record11.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr); + Record11.Counters.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr); InstrProfValueData VD3[] = {{uint64_t(callee1), 1}}; - Record11.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr); + Record11.Counters.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr); InstrProfValueData VD4[] = {{uint64_t(callee1), 1}, {uint64_t(callee2), 2}, {uint64_t(callee3), 3}}; - Record11.addValueData(IPVK_IndirectCallTarget, 4, VD4, 3, nullptr); + Record11.Counters.addValueData(IPVK_IndirectCallTarget, 4, VD4, 3, nullptr); // A different record for the same caller. - Record12.reserveSites(IPVK_IndirectCallTarget, 5); + Record12.Counters.reserveSites(IPVK_IndirectCallTarget, 5); InstrProfValueData VD02[] = {{uint64_t(callee2), 5}, {uint64_t(callee3), 3}}; - Record12.addValueData(IPVK_IndirectCallTarget, 0, VD02, 2, nullptr); + Record12.Counters.addValueData(IPVK_IndirectCallTarget, 0, VD02, 2, nullptr); // No value profile data at the second site. - Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr); + Record12.Counters.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, + nullptr); InstrProfValueData VD22[] = { {uint64_t(callee2), 1}, {uint64_t(callee3), 3}, {uint64_t(callee4), 4}}; - Record12.addValueData(IPVK_IndirectCallTarget, 2, VD22, 3, nullptr); + Record12.Counters.addValueData(IPVK_IndirectCallTarget, 2, VD22, 3, nullptr); - Record12.addValueData(IPVK_IndirectCallTarget, 3, nullptr, 0, nullptr); + Record12.Counters.addValueData(IPVK_IndirectCallTarget, 3, nullptr, 0, + nullptr); InstrProfValueData VD42[] = {{uint64_t(callee1), 1}, {uint64_t(callee2), 2}, {uint64_t(callee3), 3}}; - Record12.addValueData(IPVK_IndirectCallTarget, 4, VD42, 3, nullptr); + Record12.Counters.addValueData(IPVK_IndirectCallTarget, 4, VD42, 3, nullptr); NoError(Writer.addRecord(std::move(Record11))); // Merge profile data. @@ -539,15 +545,15 @@ Expected R = Reader->getInstrProfRecord("caller", 0x1234); ASSERT_TRUE(NoError(R.takeError())); - ASSERT_EQ(5U, R->getNumValueSites(IPVK_IndirectCallTarget)); - ASSERT_EQ(4U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); - ASSERT_EQ(0U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 1)); - ASSERT_EQ(4U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 2)); - ASSERT_EQ(1U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 3)); - ASSERT_EQ(3U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 4)); + ASSERT_EQ(5U, R->Counters.getNumValueSites(IPVK_IndirectCallTarget)); + ASSERT_EQ(4U, R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); + ASSERT_EQ(0U, R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 1)); + ASSERT_EQ(4U, R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 2)); + ASSERT_EQ(1U, R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 3)); + ASSERT_EQ(3U, R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 4)); std::unique_ptr VD = - R->getValueForSite(IPVK_IndirectCallTarget, 0); + R->Counters.getValueForSite(IPVK_IndirectCallTarget, 0); ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee2")); ASSERT_EQ(7U, VD[0].Count); ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee3")); @@ -558,7 +564,7 @@ ASSERT_EQ(1U, VD[3].Count); std::unique_ptr VD_2( - R->getValueForSite(IPVK_IndirectCallTarget, 2)); + R->Counters.getValueForSite(IPVK_IndirectCallTarget, 2)); ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee3")); ASSERT_EQ(6U, VD_2[0].Count); ASSERT_EQ(StringRef((const char *)VD_2[1].Value, 7), StringRef("callee4")); @@ -569,12 +575,12 @@ ASSERT_EQ(1U, VD_2[3].Count); std::unique_ptr VD_3( - R->getValueForSite(IPVK_IndirectCallTarget, 3)); + R->Counters.getValueForSite(IPVK_IndirectCallTarget, 3)); ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee1")); ASSERT_EQ(1U, VD_3[0].Count); std::unique_ptr VD_4( - R->getValueForSite(IPVK_IndirectCallTarget, 4)); + R->Counters.getValueForSite(IPVK_IndirectCallTarget, 4)); ASSERT_EQ(StringRef((const char *)VD_4[0].Value, 7), StringRef("callee3")); ASSERT_EQ(6U, VD_4[0].Count); ASSERT_EQ(StringRef((const char *)VD_4[1].Value, 7), StringRef("callee2")); @@ -605,18 +611,18 @@ instrprof_error::success); InstrProfRecord Record4("baz", 0x5678, {3, 4}); - Record4.reserveSites(IPVK_IndirectCallTarget, 1); + Record4.Counters.reserveSites(IPVK_IndirectCallTarget, 1); InstrProfValueData VD4[] = {{uint64_t(bar), 1}}; - Record4.addValueData(IPVK_IndirectCallTarget, 0, VD4, 1, nullptr); + Record4.Counters.addValueData(IPVK_IndirectCallTarget, 0, VD4, 1, nullptr); auto Result4 = Writer.addRecord(std::move(Record4)); ASSERT_EQ(InstrProfError::take(std::move(Result4)), instrprof_error::success); // Verify value data counter overflow. InstrProfRecord Record5("baz", 0x5678, {5, 6}); - Record5.reserveSites(IPVK_IndirectCallTarget, 1); + Record5.Counters.reserveSites(IPVK_IndirectCallTarget, 1); InstrProfValueData VD5[] = {{uint64_t(bar), Max}}; - Record5.addValueData(IPVK_IndirectCallTarget, 0, VD5, 1, nullptr); + Record5.Counters.addValueData(IPVK_IndirectCallTarget, 0, VD5, 1, nullptr); auto Result5 = Writer.addRecord(std::move(Record5)); ASSERT_EQ(InstrProfError::take(std::move(Result5)), instrprof_error::counter_overflow); @@ -628,14 +634,15 @@ Expected ReadRecord1 = Reader->getInstrProfRecord("foo", 0x1234); ASSERT_TRUE(NoError(ReadRecord1.takeError())); - ASSERT_EQ(Max, ReadRecord1->Counts[0]); + ASSERT_EQ(Max, ReadRecord1->Counters.Counts[0]); Expected ReadRecord2 = Reader->getInstrProfRecord("baz", 0x5678); ASSERT_TRUE(bool(ReadRecord2)); - ASSERT_EQ(1U, ReadRecord2->getNumValueSites(IPVK_IndirectCallTarget)); + ASSERT_EQ(1U, + ReadRecord2->Counters.getNumValueSites(IPVK_IndirectCallTarget)); std::unique_ptr VD = - ReadRecord2->getValueForSite(IPVK_IndirectCallTarget, 0); + ReadRecord2->Counters.getValueForSite(IPVK_IndirectCallTarget, 0); ASSERT_EQ(StringRef("bar"), StringRef((const char *)VD[0].Value, 3)); ASSERT_EQ(Max, VD[0].Count); } @@ -650,25 +657,27 @@ InstrProfRecord Record12(caller, 0x1234, {1, 2}); // 2 value sites. - Record11.reserveSites(IPVK_IndirectCallTarget, 2); + Record11.Counters.reserveSites(IPVK_IndirectCallTarget, 2); InstrProfValueData VD0[255]; for (int I = 0; I < 255; I++) { VD0[I].Value = 2 * I; VD0[I].Count = 2 * I + 1000; } - Record11.addValueData(IPVK_IndirectCallTarget, 0, VD0, 255, nullptr); - Record11.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr); + Record11.Counters.addValueData(IPVK_IndirectCallTarget, 0, VD0, 255, nullptr); + Record11.Counters.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, + nullptr); - Record12.reserveSites(IPVK_IndirectCallTarget, 2); + Record12.Counters.reserveSites(IPVK_IndirectCallTarget, 2); InstrProfValueData VD1[255]; for (int I = 0; I < 255; I++) { VD1[I].Value = 2 * I + 1; VD1[I].Count = 2 * I + 1001; } - Record12.addValueData(IPVK_IndirectCallTarget, 0, VD1, 255, nullptr); - Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr); + Record12.Counters.addValueData(IPVK_IndirectCallTarget, 0, VD1, 255, nullptr); + Record12.Counters.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, + nullptr); NoError(Writer.addRecord(std::move(Record11))); // Merge profile data. @@ -680,60 +689,61 @@ Expected R = Reader->getInstrProfRecord("caller", 0x1234); ASSERT_TRUE(NoError(R.takeError())); std::unique_ptr VD( - R->getValueForSite(IPVK_IndirectCallTarget, 0)); - ASSERT_EQ(2U, R->getNumValueSites(IPVK_IndirectCallTarget)); - ASSERT_EQ(255U, R->getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); + R->Counters.getValueForSite(IPVK_IndirectCallTarget, 0)); + ASSERT_EQ(2U, R->Counters.getNumValueSites(IPVK_IndirectCallTarget)); + ASSERT_EQ(255U, + R->Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); for (unsigned I = 0; I < 255; I++) { ASSERT_EQ(VD[I].Value, 509 - I); ASSERT_EQ(VD[I].Count, 1509 - I); } } -static void addValueProfData(InstrProfRecord &Record) { - Record.reserveSites(IPVK_IndirectCallTarget, 5); +static void addValueProfData(InstrProfRecord::CounterHolder &Counters) { + Counters.reserveSites(IPVK_IndirectCallTarget, 5); InstrProfValueData VD0[] = {{uint64_t(callee1), 400}, {uint64_t(callee2), 1000}, {uint64_t(callee3), 500}, {uint64_t(callee4), 300}, {uint64_t(callee5), 100}}; - Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 5, nullptr); + Counters.addValueData(IPVK_IndirectCallTarget, 0, VD0, 5, nullptr); InstrProfValueData VD1[] = {{uint64_t(callee5), 800}, {uint64_t(callee3), 1000}, {uint64_t(callee2), 2500}, {uint64_t(callee1), 1300}}; - Record.addValueData(IPVK_IndirectCallTarget, 1, VD1, 4, nullptr); + Counters.addValueData(IPVK_IndirectCallTarget, 1, VD1, 4, nullptr); InstrProfValueData VD2[] = {{uint64_t(callee6), 800}, {uint64_t(callee3), 1000}, {uint64_t(callee4), 5500}}; - Record.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr); + Counters.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr); InstrProfValueData VD3[] = {{uint64_t(callee2), 1800}, {uint64_t(callee3), 2000}}; - Record.addValueData(IPVK_IndirectCallTarget, 3, VD3, 2, nullptr); - Record.addValueData(IPVK_IndirectCallTarget, 4, nullptr, 0, nullptr); + Counters.addValueData(IPVK_IndirectCallTarget, 3, VD3, 2, nullptr); + Counters.addValueData(IPVK_IndirectCallTarget, 4, nullptr, 0, nullptr); } TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write) { - InstrProfRecord SrcRecord("caller", 0x1234, {1ULL << 31, 2}); - addValueProfData(SrcRecord); + InstrProfRecord::CounterHolder SrcCounters({1ULL << 31, 2}); + addValueProfData(SrcCounters); std::unique_ptr VPData = - ValueProfData::serializeFrom(SrcRecord); + ValueProfData::serializeFrom(SrcCounters); - InstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2}); - VPData->deserializeTo(Record, nullptr); + InstrProfRecord::CounterHolder Counters({1ULL << 31, 2}); + VPData->deserializeTo(Counters, nullptr); - // Now read data from Record and sanity check the data - ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget)); - ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); - ASSERT_EQ(4U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 1)); - ASSERT_EQ(3U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 2)); - ASSERT_EQ(2U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 3)); - ASSERT_EQ(0U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 4)); + // Now read data from Counters and sanity check the data + ASSERT_EQ(5U, Counters.getNumValueSites(IPVK_IndirectCallTarget)); + ASSERT_EQ(5U, Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); + ASSERT_EQ(4U, Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 1)); + ASSERT_EQ(3U, Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 2)); + ASSERT_EQ(2U, Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 3)); + ASSERT_EQ(0U, Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 4)); auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) { return VD1.Count > VD2.Count; }; std::unique_ptr VD_0( - Record.getValueForSite(IPVK_IndirectCallTarget, 0)); + Counters.getValueForSite(IPVK_IndirectCallTarget, 0)); std::sort(&VD_0[0], &VD_0[5], Cmp); ASSERT_EQ(StringRef((const char *)VD_0[0].Value, 7), StringRef("callee2")); ASSERT_EQ(1000U, VD_0[0].Count); @@ -747,7 +757,7 @@ ASSERT_EQ(100U, VD_0[4].Count); std::unique_ptr VD_1( - Record.getValueForSite(IPVK_IndirectCallTarget, 1)); + Counters.getValueForSite(IPVK_IndirectCallTarget, 1)); std::sort(&VD_1[0], &VD_1[4], Cmp); ASSERT_EQ(StringRef((const char *)VD_1[0].Value, 7), StringRef("callee2")); ASSERT_EQ(2500U, VD_1[0].Count); @@ -759,7 +769,7 @@ ASSERT_EQ(800U, VD_1[3].Count); std::unique_ptr VD_2( - Record.getValueForSite(IPVK_IndirectCallTarget, 2)); + Counters.getValueForSite(IPVK_IndirectCallTarget, 2)); std::sort(&VD_2[0], &VD_2[3], Cmp); ASSERT_EQ(StringRef((const char *)VD_2[0].Value, 7), StringRef("callee4")); ASSERT_EQ(5500U, VD_2[0].Count); @@ -769,7 +779,7 @@ ASSERT_EQ(800U, VD_2[2].Count); std::unique_ptr VD_3( - Record.getValueForSite(IPVK_IndirectCallTarget, 3)); + Counters.getValueForSite(IPVK_IndirectCallTarget, 3)); std::sort(&VD_3[0], &VD_3[2], Cmp); ASSERT_EQ(StringRef((const char *)VD_3[0].Value, 7), StringRef("callee3")); ASSERT_EQ(2000U, VD_3[0].Count); @@ -779,12 +789,12 @@ TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write_mapping) { - InstrProfRecord SrcRecord("caller", 0x1234, {1ULL << 31, 2}); - addValueProfData(SrcRecord); + InstrProfRecord::CounterHolder SrcCounters({1ULL << 31, 2}); + addValueProfData(SrcCounters); std::unique_ptr VPData = - ValueProfData::serializeFrom(SrcRecord); + ValueProfData::serializeFrom(SrcCounters); - InstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2}); + InstrProfRecord::CounterHolder Counters({1ULL << 31, 2}); InstrProfSymtab Symtab; Symtab.mapAddress(uint64_t(callee1), 0x1000ULL); Symtab.mapAddress(uint64_t(callee2), 0x2000ULL); @@ -793,17 +803,17 @@ // Missing mapping for callee5 Symtab.finalizeSymtab(); - VPData->deserializeTo(Record, &Symtab.getAddrHashMap()); + VPData->deserializeTo(Counters, &Symtab.getAddrHashMap()); - // Now read data from Record and sanity check the data - ASSERT_EQ(5U, Record.getNumValueSites(IPVK_IndirectCallTarget)); - ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); + // Now read data from Counters and sanity check the data + ASSERT_EQ(5U, Counters.getNumValueSites(IPVK_IndirectCallTarget)); + ASSERT_EQ(5U, Counters.getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) { return VD1.Count > VD2.Count; }; std::unique_ptr VD_0( - Record.getValueForSite(IPVK_IndirectCallTarget, 0)); + Counters.getValueForSite(IPVK_IndirectCallTarget, 0)); std::sort(&VD_0[0], &VD_0[5], Cmp); ASSERT_EQ(VD_0[0].Value, 0x2000ULL); ASSERT_EQ(1000U, VD_0[0].Count);