diff options
Diffstat (limited to 'llvm/lib/ProfileData/SampleProfReader.cpp')
-rw-r--r-- | llvm/lib/ProfileData/SampleProfReader.cpp | 98 |
1 files changed, 95 insertions, 3 deletions
diff --git a/llvm/lib/ProfileData/SampleProfReader.cpp b/llvm/lib/ProfileData/SampleProfReader.cpp index cf78740..b8b55f7 100644 --- a/llvm/lib/ProfileData/SampleProfReader.cpp +++ b/llvm/lib/ProfileData/SampleProfReader.cpp @@ -197,8 +197,30 @@ enum class LineType { CallSiteProfile, BodyProfile, Metadata, + VirtualCallTypeProfile, }; +static bool parseTypeCountMap(StringRef Input, + DenseMap<StringRef, uint64_t> &TypeCountMap) { + for (size_t Index = Input.find_first_not_of(' '); Index != StringRef::npos;) { + size_t n1 = Input.find(':', Index); + if (n1 == StringRef::npos) + return false; // No colon found, invalid format. + StringRef TypeName = Input.substr(Index, n1 - Index); + // n2 is the start index of count. + size_t n2 = n1 + 1; + // n3 is the start index after the 'target:count' pair. + size_t n3 = Input.find_first_of(' ', n2); + uint64_t Count; + if (Input.substr(n2, n3 - n2).getAsInteger(10, Count)) + return false; // Invalid count. + TypeCountMap[TypeName] = Count; + Index = (n3 == StringRef::npos) ? StringRef::npos + : Input.find_first_not_of(' ', n3); + } + return true; +} + /// Parse \p Input as line sample. /// /// \param Input input line. @@ -215,6 +237,7 @@ static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth, uint64_t &NumSamples, uint32_t &LineOffset, uint32_t &Discriminator, StringRef &CalleeName, DenseMap<StringRef, uint64_t> &TargetCountMap, + DenseMap<StringRef, uint64_t> &TypeCountMap, uint64_t &FunctionHash, uint32_t &Attributes, bool &IsFlat) { for (Depth = 0; Input[Depth] == ' '; Depth++) @@ -289,6 +312,7 @@ static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth, n4 = AfterColon.find_first_of(' '); n4 = (n4 != StringRef::npos) ? n3 + n4 + 1 : Rest.size(); StringRef WordAfterColon = Rest.substr(n3 + 1, n4 - n3 - 1); + // Break the loop if parsing integer succeeded. if (!WordAfterColon.getAsInteger(10, count)) break; @@ -306,6 +330,10 @@ static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth, // Change n3 to the next blank space after colon + integer pair. n3 = n4; } + } else if (Rest.starts_with(kVTableProfPrefix)) { + LineTy = LineType::VirtualCallTypeProfile; + return parseTypeCountMap(Rest.substr(strlen(kVTableProfPrefix)), + TypeCountMap); } else { LineTy = LineType::CallSiteProfile; size_t n3 = Rest.find_last_of(':'); @@ -374,14 +402,15 @@ std::error_code SampleProfileReaderText::readImpl() { uint64_t NumSamples; StringRef FName; DenseMap<StringRef, uint64_t> TargetCountMap; + DenseMap<StringRef, uint64_t> TypeCountMap; uint32_t Depth, LineOffset, Discriminator; LineType LineTy; uint64_t FunctionHash = 0; uint32_t Attributes = 0; bool IsFlat = false; if (!ParseLine(*LineIt, LineTy, Depth, NumSamples, LineOffset, - Discriminator, FName, TargetCountMap, FunctionHash, - Attributes, IsFlat)) { + Discriminator, FName, TargetCountMap, TypeCountMap, + FunctionHash, Attributes, IsFlat)) { reportError(LineIt.line_number(), "Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found " + *LineIt); @@ -410,6 +439,14 @@ std::error_code SampleProfileReaderText::readImpl() { DepthMetadata = 0; break; } + + case LineType::VirtualCallTypeProfile: { + mergeSampleProfErrors( + Result, InlineStack.back()->addCallsiteVTableTypeProfAt( + LineLocation(LineOffset, Discriminator), TypeCountMap)); + break; + } + case LineType::BodyProfile: { FunctionSamples &FProfile = *InlineStack.back(); for (const auto &name_count : TargetCountMap) { @@ -592,6 +629,59 @@ SampleProfileReaderBinary::readSampleContextFromTable() { } std::error_code +SampleProfileReaderBinary::readVTableTypeCountMap(TypeCountMap &M) { + auto NumVTableTypes = readNumber<uint32_t>(); + if (std::error_code EC = NumVTableTypes.getError()) + return EC; + + for (uint32_t I = 0; I < *NumVTableTypes; ++I) { + auto VTableType(readStringFromTable()); + if (std::error_code EC = VTableType.getError()) + return EC; + + auto VTableSamples = readNumber<uint64_t>(); + if (std::error_code EC = VTableSamples.getError()) + return EC; + + if (!M.insert(std::make_pair(*VTableType, *VTableSamples)).second) + return sampleprof_error::duplicate_vtable_type; + } + return sampleprof_error::success; +} + +std::error_code +SampleProfileReaderBinary::readCallsiteVTableProf(FunctionSamples &FProfile) { + if (!ReadVTableProf) + return sampleprof_error::success; + + // Read the vtable type profile for the callsite. + auto NumCallsites = readNumber<uint32_t>(); + if (std::error_code EC = NumCallsites.getError()) + return EC; + + for (uint32_t I = 0; I < *NumCallsites; ++I) { + auto LineOffset = readNumber<uint64_t>(); + if (std::error_code EC = LineOffset.getError()) + return EC; + + if (!isOffsetLegal(*LineOffset)) + return sampleprof_error::illegal_line_offset; + + auto Discriminator = readNumber<uint64_t>(); + if (std::error_code EC = Discriminator.getError()) + return EC; + + // Here we handle FS discriminators: + const uint32_t DiscriminatorVal = (*Discriminator) & getDiscriminatorMask(); + + if (std::error_code EC = readVTableTypeCountMap(FProfile.getTypeSamplesAt( + LineLocation(*LineOffset, DiscriminatorVal)))) + return EC; + } + return sampleprof_error::success; +} + +std::error_code SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) { auto NumSamples = readNumber<uint64_t>(); if (std::error_code EC = NumSamples.getError()) @@ -671,7 +761,7 @@ SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) { return EC; } - return sampleprof_error::success; + return readCallsiteVTableProf(FProfile); } std::error_code @@ -733,6 +823,8 @@ std::error_code SampleProfileReaderExtBinaryBase::readOneSection( FunctionSamples::ProfileIsPreInlined = ProfileIsPreInlined = true; if (hasSecFlag(Entry, SecProfSummaryFlags::SecFlagFSDiscriminator)) FunctionSamples::ProfileIsFS = ProfileIsFS = true; + if (hasSecFlag(Entry, SecProfSummaryFlags::SecFlagHasVTableTypeProf)) + ReadVTableProf = true; break; case SecNameTable: { bool FixedLengthMD5 = |