diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-02-10 16:44:39 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:39 +0300 |
commit | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (patch) | |
tree | 64175d5cadab313b3e7039ebaa06c5bc3295e274 /contrib/libs/llvm12/lib/ProfileData | |
parent | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (diff) | |
download | ydb-e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0.tar.gz |
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/llvm12/lib/ProfileData')
13 files changed, 1222 insertions, 1222 deletions
diff --git a/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMapping.cpp b/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMapping.cpp index 3307b782e2..cdbcde50d3 100644 --- a/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -249,12 +249,12 @@ Error CoverageMapping::loadFunctionRecord( consumeError(std::move(E)); return Error::success(); } - Expected<int64_t> AltExecutionCount = Ctx.evaluate(Region.FalseCount); - if (auto E = AltExecutionCount.takeError()) { - consumeError(std::move(E)); - return Error::success(); - } - Function.pushRegion(Region, *ExecutionCount, *AltExecutionCount); + Expected<int64_t> AltExecutionCount = Ctx.evaluate(Region.FalseCount); + if (auto E = AltExecutionCount.takeError()) { + consumeError(std::move(E)); + return Error::success(); + } + Function.pushRegion(Region, *ExecutionCount, *AltExecutionCount); } // Don't create records for (filenames, function) pairs we've already seen. @@ -490,15 +490,15 @@ class SegmentBuilder { if (CurStartLoc == CR.value().endLoc()) { // Avoid making zero-length regions active. If it's the last region, // emit a skipped segment. Otherwise use its predecessor's count. - const bool Skipped = - (CR.index() + 1) == Regions.size() || - CR.value().Kind == CounterMappingRegion::SkippedRegion; + const bool Skipped = + (CR.index() + 1) == Regions.size() || + CR.value().Kind == CounterMappingRegion::SkippedRegion; startSegment(ActiveRegions.empty() ? CR.value() : *ActiveRegions.back(), CurStartLoc, !GapRegion, Skipped); - // If it is skipped segment, create a segment with last pushed - // regions's count at CurStartLoc. - if (Skipped && !ActiveRegions.empty()) - startSegment(*ActiveRegions.back(), CurStartLoc, false); + // If it is skipped segment, create a segment with last pushed + // regions's count at CurStartLoc. + if (Skipped && !ActiveRegions.empty()) + startSegment(*ActiveRegions.back(), CurStartLoc, false); continue; } if (CR.index() + 1 == Regions.size() || @@ -598,8 +598,8 @@ public: const auto &L = Segments[I - 1]; const auto &R = Segments[I]; if (!(L.Line < R.Line) && !(L.Line == R.Line && L.Col < R.Col)) { - if (L.Line == R.Line && L.Col == R.Col && !L.HasCount) - continue; + if (L.Line == R.Line && L.Col == R.Col && !L.HasCount) + continue; LLVM_DEBUG(dbgs() << " ! Segment " << L.Line << ":" << L.Col << " followed by " << R.Line << ":" << R.Col << "\n"); assert(false && "Coverage segments not unique or sorted"); @@ -616,7 +616,7 @@ public: std::vector<StringRef> CoverageMapping::getUniqueSourceFiles() const { std::vector<StringRef> Filenames; for (const auto &Function : getCoveredFunctions()) - llvm::append_range(Filenames, Function.Filenames); + llvm::append_range(Filenames, Function.Filenames); llvm::sort(Filenames); auto Last = std::unique(Filenames.begin(), Filenames.end()); Filenames.erase(Last, Filenames.end()); @@ -676,10 +676,10 @@ CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const { if (MainFileID && isExpansion(CR, *MainFileID)) FileCoverage.Expansions.emplace_back(CR, Function); } - // Capture branch regions specific to the function (excluding expansions). - for (const auto &CR : Function.CountedBranchRegions) - if (FileIDs.test(CR.FileID) && (CR.FileID == CR.ExpandedFileID)) - FileCoverage.BranchRegions.push_back(CR); + // Capture branch regions specific to the function (excluding expansions). + for (const auto &CR : Function.CountedBranchRegions) + if (FileIDs.test(CR.FileID) && (CR.FileID == CR.ExpandedFileID)) + FileCoverage.BranchRegions.push_back(CR); } LLVM_DEBUG(dbgs() << "Emitting segments for file: " << Filename << "\n"); @@ -727,10 +727,10 @@ CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const { if (isExpansion(CR, *MainFileID)) FunctionCoverage.Expansions.emplace_back(CR, Function); } - // Capture branch regions specific to the function (excluding expansions). - for (const auto &CR : Function.CountedBranchRegions) - if (CR.FileID == *MainFileID) - FunctionCoverage.BranchRegions.push_back(CR); + // Capture branch regions specific to the function (excluding expansions). + for (const auto &CR : Function.CountedBranchRegions) + if (CR.FileID == *MainFileID) + FunctionCoverage.BranchRegions.push_back(CR); LLVM_DEBUG(dbgs() << "Emitting segments for function: " << Function.Name << "\n"); @@ -750,10 +750,10 @@ CoverageData CoverageMapping::getCoverageForExpansion( if (isExpansion(CR, Expansion.FileID)) ExpansionCoverage.Expansions.emplace_back(CR, Expansion.Function); } - for (const auto &CR : Expansion.Function.CountedBranchRegions) - // Capture branch regions that only pertain to the corresponding expansion. - if (CR.FileID == Expansion.FileID) - ExpansionCoverage.BranchRegions.push_back(CR); + for (const auto &CR : Expansion.Function.CountedBranchRegions) + // Capture branch regions that only pertain to the corresponding expansion. + if (CR.FileID == Expansion.FileID) + ExpansionCoverage.BranchRegions.push_back(CR); LLVM_DEBUG(dbgs() << "Emitting segments for expansion of file " << Expansion.FileID << "\n"); @@ -831,8 +831,8 @@ static std::string getCoverageMapErrString(coveragemap_error Err) { return "Malformed coverage data"; case coveragemap_error::decompression_failed: return "Failed to decompress coverage data (zlib)"; - case coveragemap_error::invalid_or_missing_arch_specifier: - return "`-arch` specifier is invalid or missing for universal binary"; + case coveragemap_error::invalid_or_missing_arch_specifier: + return "`-arch` specifier is invalid or missing for universal binary"; } llvm_unreachable("A value of coveragemap_error has no message."); } diff --git a/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingReader.cpp index 54b63a2af0..1acdcb4beb 100644 --- a/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ b/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingReader.cpp @@ -213,7 +213,7 @@ Error RawCoverageMappingReader::readMappingRegionsSubArray( return Err; unsigned LineStart = 0; for (size_t I = 0; I < NumRegions; ++I) { - Counter C, C2; + Counter C, C2; CounterMappingRegion::RegionKind Kind = CounterMappingRegion::CodeRegion; // Read the combined counter + region kind. @@ -223,18 +223,18 @@ Error RawCoverageMappingReader::readMappingRegionsSubArray( return Err; unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask; uint64_t ExpandedFileID = 0; - - // If Tag does not represent a ZeroCounter, then it is understood to refer - // to a counter or counter expression with region kind assumed to be - // "CodeRegion". In that case, EncodedCounterAndRegion actually encodes the - // referenced counter or counter expression (and nothing else). - // - // If Tag represents a ZeroCounter and EncodingExpansionRegionBit is set, - // then EncodedCounterAndRegion is interpreted to represent an - // ExpansionRegion. In all other cases, EncodedCounterAndRegion is - // interpreted to refer to a specific region kind, after which additional - // fields may be read (e.g. BranchRegions have two encoded counters that - // follow an encoded region kind value). + + // If Tag does not represent a ZeroCounter, then it is understood to refer + // to a counter or counter expression with region kind assumed to be + // "CodeRegion". In that case, EncodedCounterAndRegion actually encodes the + // referenced counter or counter expression (and nothing else). + // + // If Tag represents a ZeroCounter and EncodingExpansionRegionBit is set, + // then EncodedCounterAndRegion is interpreted to represent an + // ExpansionRegion. In all other cases, EncodedCounterAndRegion is + // interpreted to refer to a specific region kind, after which additional + // fields may be read (e.g. BranchRegions have two encoded counters that + // follow an encoded region kind value). if (Tag != Counter::Zero) { if (auto Err = decodeCounter(EncodedCounterAndRegion, C)) return Err; @@ -255,14 +255,14 @@ Error RawCoverageMappingReader::readMappingRegionsSubArray( case CounterMappingRegion::SkippedRegion: Kind = CounterMappingRegion::SkippedRegion; break; - case CounterMappingRegion::BranchRegion: - // For a Branch Region, read two successive counters. - Kind = CounterMappingRegion::BranchRegion; - if (auto Err = readCounter(C)) - return Err; - if (auto Err = readCounter(C2)) - return Err; - break; + case CounterMappingRegion::BranchRegion: + // For a Branch Region, read two successive counters. + Kind = CounterMappingRegion::BranchRegion; + if (auto Err = readCounter(C)) + return Err; + if (auto Err = readCounter(C2)) + return Err; + break; default: return make_error<CoverageMapError>(coveragemap_error::malformed); } @@ -314,7 +314,7 @@ Error RawCoverageMappingReader::readMappingRegionsSubArray( dbgs() << "\n"; }); - auto CMR = CounterMappingRegion(C, C2, InferredFileID, ExpandedFileID, + auto CMR = CounterMappingRegion(C, C2, InferredFileID, ExpandedFileID, LineStart, ColumnStart, LineStart + NumLines, ColumnEnd, Kind); if (CMR.startLoc() > CMR.endLoc()) @@ -620,7 +620,7 @@ public: CovBuf += FilenamesSize; FilenameRange FileRange(FilenamesBegin, Filenames.size() - FilenamesBegin); - if (Version >= CovMapVersion::Version4) { + if (Version >= CovMapVersion::Version4) { // Map a hash of the filenames region to the filename range associated // with this coverage header. int64_t FilenamesRef = @@ -648,7 +648,7 @@ public: // This is a no-op in Version4 (coverage mappings are not affixed to the // coverage header). const char *MappingBuf = CovBuf; - if (Version >= CovMapVersion::Version4 && CoverageSize != 0) + if (Version >= CovMapVersion::Version4 && CoverageSize != 0) return make_error<CoverageMapError>(coveragemap_error::malformed); CovBuf += CoverageSize; const char *MappingEnd = CovBuf; @@ -702,7 +702,7 @@ public: if (FileRange && !FileRange->isInvalid()) { StringRef Mapping = CFR->template getCoverageMapping<Endian>(OutOfLineMappingBuf); - if (Version >= CovMapVersion::Version4 && + if (Version >= CovMapVersion::Version4 && Mapping.data() + Mapping.size() > FuncRecBufEnd) return make_error<CoverageMapError>(coveragemap_error::malformed); if (Error Err = insertFunctionRecordIfNeeded(CFR, Mapping, *FileRange)) @@ -731,7 +731,7 @@ Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get( case CovMapVersion::Version2: case CovMapVersion::Version3: case CovMapVersion::Version4: - case CovMapVersion::Version5: + case CovMapVersion::Version5: // Decompress the name data. if (Error E = P.create(P.getNameData())) return std::move(E); @@ -744,9 +744,9 @@ Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get( else if (Version == CovMapVersion::Version4) return std::make_unique<VersionedCovMapFuncRecordReader< CovMapVersion::Version4, IntPtrT, Endian>>(P, R, F); - else if (Version == CovMapVersion::Version5) - return std::make_unique<VersionedCovMapFuncRecordReader< - CovMapVersion::Version5, IntPtrT, Endian>>(P, R, F); + else if (Version == CovMapVersion::Version5) + return std::make_unique<VersionedCovMapFuncRecordReader< + CovMapVersion::Version5, IntPtrT, Endian>>(P, R, F); } llvm_unreachable("Unsupported version"); } @@ -790,7 +790,7 @@ static Error readCoverageMappingData( } // In Version4, function records are not affixed to coverage headers. Read // the records from their dedicated section. - if (Version >= CovMapVersion::Version4) + if (Version >= CovMapVersion::Version4) return Reader->readFunctionRecords(FuncRecBuf, FuncRecBufEnd, None, nullptr, nullptr); return Error::success(); @@ -974,19 +974,19 @@ loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch) { BytesInAddress, Endian); } -/// Determine whether \p Arch is invalid or empty, given \p Bin. -static bool isArchSpecifierInvalidOrMissing(Binary *Bin, StringRef Arch) { - // If we have a universal binary and Arch doesn't identify any of its slices, - // it's user error. - if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin)) { - for (auto &ObjForArch : Universal->objects()) - if (Arch == ObjForArch.getArchFlagName()) - return false; - return true; - } - return false; -} - +/// Determine whether \p Arch is invalid or empty, given \p Bin. +static bool isArchSpecifierInvalidOrMissing(Binary *Bin, StringRef Arch) { + // If we have a universal binary and Arch doesn't identify any of its slices, + // it's user error. + if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin)) { + for (auto &ObjForArch : Universal->objects()) + if (Arch == ObjForArch.getArchFlagName()) + return false; + return true; + } + return false; +} + Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>> BinaryCoverageReader::create( MemoryBufferRef ObjectBuffer, StringRef Arch, @@ -1007,10 +1007,10 @@ BinaryCoverageReader::create( return BinOrErr.takeError(); std::unique_ptr<Binary> Bin = std::move(BinOrErr.get()); - if (isArchSpecifierInvalidOrMissing(Bin.get(), Arch)) - return make_error<CoverageMapError>( - coveragemap_error::invalid_or_missing_arch_specifier); - + if (isArchSpecifierInvalidOrMissing(Bin.get(), Arch)) + return make_error<CoverageMapError>( + coveragemap_error::invalid_or_missing_arch_specifier); + // MachO universal binaries which contain archives need to be treated as // archives, not as regular binaries. if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) { diff --git a/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingWriter.cpp b/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingWriter.cpp index a9ad67f63b..65b83d1f41 100644 --- a/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingWriter.cpp +++ b/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingWriter.cpp @@ -80,14 +80,14 @@ public: ArrayRef<CounterMappingRegion> MappingRegions) : Expressions(Expressions) { AdjustedExpressionIDs.resize(Expressions.size(), 0); - for (const auto &I : MappingRegions) { + for (const auto &I : MappingRegions) { mark(I.Count); - mark(I.FalseCount); - } - for (const auto &I : MappingRegions) { + mark(I.FalseCount); + } + for (const auto &I : MappingRegions) { gatherUsed(I.Count); - gatherUsed(I.FalseCount); - } + gatherUsed(I.FalseCount); + } } void mark(Counter C) { @@ -205,7 +205,7 @@ void CoverageMappingWriter::write(raw_ostream &OS) { PrevLineStart = 0; } Counter Count = Minimizer.adjust(I->Count); - Counter FalseCount = Minimizer.adjust(I->FalseCount); + Counter FalseCount = Minimizer.adjust(I->FalseCount); switch (I->Kind) { case CounterMappingRegion::CodeRegion: case CounterMappingRegion::GapRegion: @@ -231,13 +231,13 @@ void CoverageMappingWriter::write(raw_ostream &OS) { << Counter::EncodingCounterTagAndExpansionRegionTagBits, OS); break; - case CounterMappingRegion::BranchRegion: - encodeULEB128(unsigned(I->Kind) - << Counter::EncodingCounterTagAndExpansionRegionTagBits, - OS); - writeCounter(MinExpressions, Count, OS); - writeCounter(MinExpressions, FalseCount, OS); - break; + case CounterMappingRegion::BranchRegion: + encodeULEB128(unsigned(I->Kind) + << Counter::EncodingCounterTagAndExpansionRegionTagBits, + OS); + writeCounter(MinExpressions, Count, OS); + writeCounter(MinExpressions, FalseCount, OS); + break; } assert(I->LineStart >= PrevLineStart); encodeULEB128(I->LineStart - PrevLineStart, OS); diff --git a/contrib/libs/llvm12/lib/ProfileData/Coverage/ya.make b/contrib/libs/llvm12/lib/ProfileData/Coverage/ya.make index efd850fcac..7485f519d1 100644 --- a/contrib/libs/llvm12/lib/ProfileData/Coverage/ya.make +++ b/contrib/libs/llvm12/lib/ProfileData/Coverage/ya.make @@ -12,11 +12,11 @@ LICENSE(Apache-2.0 WITH LLVM-exception) LICENSE_TEXTS(.yandex_meta/licenses.list.txt) PEERDIR( - contrib/libs/llvm12 - contrib/libs/llvm12/lib/IR - contrib/libs/llvm12/lib/Object - contrib/libs/llvm12/lib/ProfileData - contrib/libs/llvm12/lib/Support + contrib/libs/llvm12 + contrib/libs/llvm12/lib/IR + contrib/libs/llvm12/lib/Object + contrib/libs/llvm12/lib/ProfileData + contrib/libs/llvm12/lib/Support ) ADDINCL( diff --git a/contrib/libs/llvm12/lib/ProfileData/GCOV.cpp b/contrib/libs/llvm12/lib/ProfileData/GCOV.cpp index aef75c8c61..3332a89860 100644 --- a/contrib/libs/llvm12/lib/ProfileData/GCOV.cpp +++ b/contrib/libs/llvm12/lib/ProfileData/GCOV.cpp @@ -14,16 +14,16 @@ #include "llvm/ProfileData/GCOV.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Config/llvm-config.h" -#include "llvm/Demangle/Demangle.h" +#include "llvm/Demangle/Demangle.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" -#include "llvm/Support/MD5.h" +#include "llvm/Support/MD5.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <system_error> -#include <unordered_map> +#include <unordered_map> using namespace llvm; @@ -41,59 +41,59 @@ enum : uint32_t { GCOV_TAG_PROGRAM_SUMMARY = 0xa3000000, }; -namespace { -struct Summary { - Summary(StringRef Name) : Name(Name) {} - - StringRef Name; - uint64_t lines = 0; - uint64_t linesExec = 0; - uint64_t branches = 0; - uint64_t branchesExec = 0; - uint64_t branchesTaken = 0; -}; - -struct LineInfo { - SmallVector<const GCOVBlock *, 1> blocks; - uint64_t count = 0; - bool exists = false; -}; - -struct SourceInfo { - StringRef filename; - SmallString<0> displayName; - std::vector<std::vector<const GCOVFunction *>> startLineToFunctions; - std::vector<LineInfo> lines; - bool ignored = false; - SourceInfo(StringRef filename) : filename(filename) {} -}; - -class Context { -public: - Context(const GCOV::Options &Options) : options(Options) {} - void print(StringRef filename, StringRef gcno, StringRef gcda, - GCOVFile &file); - -private: - std::string getCoveragePath(StringRef filename, StringRef mainFilename) const; - void printFunctionDetails(const GCOVFunction &f, raw_ostream &os) const; - void printBranchInfo(const GCOVBlock &Block, uint32_t &edgeIdx, - raw_ostream &OS) const; - void printSummary(const Summary &summary, raw_ostream &os) const; - - void collectFunction(GCOVFunction &f, Summary &summary); - void collectSourceLine(SourceInfo &si, Summary *summary, LineInfo &line, - size_t lineNum) const; - void collectSource(SourceInfo &si, Summary &summary) const; - void annotateSource(SourceInfo &si, const GCOVFile &file, StringRef gcno, - StringRef gcda, raw_ostream &os) const; - void printSourceToIntermediate(const SourceInfo &si, raw_ostream &os) const; - - const GCOV::Options &options; - std::vector<SourceInfo> sources; -}; -} // namespace - +namespace { +struct Summary { + Summary(StringRef Name) : Name(Name) {} + + StringRef Name; + uint64_t lines = 0; + uint64_t linesExec = 0; + uint64_t branches = 0; + uint64_t branchesExec = 0; + uint64_t branchesTaken = 0; +}; + +struct LineInfo { + SmallVector<const GCOVBlock *, 1> blocks; + uint64_t count = 0; + bool exists = false; +}; + +struct SourceInfo { + StringRef filename; + SmallString<0> displayName; + std::vector<std::vector<const GCOVFunction *>> startLineToFunctions; + std::vector<LineInfo> lines; + bool ignored = false; + SourceInfo(StringRef filename) : filename(filename) {} +}; + +class Context { +public: + Context(const GCOV::Options &Options) : options(Options) {} + void print(StringRef filename, StringRef gcno, StringRef gcda, + GCOVFile &file); + +private: + std::string getCoveragePath(StringRef filename, StringRef mainFilename) const; + void printFunctionDetails(const GCOVFunction &f, raw_ostream &os) const; + void printBranchInfo(const GCOVBlock &Block, uint32_t &edgeIdx, + raw_ostream &OS) const; + void printSummary(const Summary &summary, raw_ostream &os) const; + + void collectFunction(GCOVFunction &f, Summary &summary); + void collectSourceLine(SourceInfo &si, Summary *summary, LineInfo &line, + size_t lineNum) const; + void collectSource(SourceInfo &si, Summary &summary) const; + void annotateSource(SourceInfo &si, const GCOVFile &file, StringRef gcno, + StringRef gcda, raw_ostream &os) const; + void printSourceToIntermediate(const SourceInfo &si, raw_ostream &os) const; + + const GCOV::Options &options; + std::vector<SourceInfo> sources; +}; +} // namespace + //===----------------------------------------------------------------------===// // GCOVFile implementation. @@ -111,13 +111,13 @@ bool GCOVFile::readGCNO(GCOVBuffer &buf) { buf.getWord(); // hasUnexecutedBlocks uint32_t tag, length; - GCOVFunction *fn = nullptr; + GCOVFunction *fn = nullptr; while ((tag = buf.getWord())) { if (!buf.readInt(length)) return false; if (tag == GCOV_TAG_FUNCTION) { - functions.push_back(std::make_unique<GCOVFunction>(*this)); - fn = functions.back().get(); + functions.push_back(std::make_unique<GCOVFunction>(*this)); + fn = functions.back().get(); fn->ident = buf.getWord(); fn->linenoChecksum = buf.getWord(); if (Version >= GCOV::V407) @@ -145,40 +145,40 @@ bool GCOVFile::readGCNO(GCOVBuffer &buf) { if (Version < GCOV::V800) { for (uint32_t i = 0; i != length; ++i) { buf.getWord(); // Ignored block flags - fn->blocks.push_back(std::make_unique<GCOVBlock>(i)); + fn->blocks.push_back(std::make_unique<GCOVBlock>(i)); } } else { uint32_t num = buf.getWord(); for (uint32_t i = 0; i != num; ++i) - fn->blocks.push_back(std::make_unique<GCOVBlock>(i)); + fn->blocks.push_back(std::make_unique<GCOVBlock>(i)); } } else if (tag == GCOV_TAG_ARCS && fn) { uint32_t srcNo = buf.getWord(); - if (srcNo >= fn->blocks.size()) { + if (srcNo >= fn->blocks.size()) { errs() << "unexpected block number: " << srcNo << " (in " - << fn->blocks.size() << ")\n"; + << fn->blocks.size() << ")\n"; return false; } - GCOVBlock *src = fn->blocks[srcNo].get(); + GCOVBlock *src = fn->blocks[srcNo].get(); for (uint32_t i = 0, e = (length - 1) / 2; i != e; ++i) { uint32_t dstNo = buf.getWord(), flags = buf.getWord(); - GCOVBlock *dst = fn->blocks[dstNo].get(); - auto arc = std::make_unique<GCOVArc>(*src, *dst, flags); + GCOVBlock *dst = fn->blocks[dstNo].get(); + auto arc = std::make_unique<GCOVArc>(*src, *dst, flags); src->addDstEdge(arc.get()); dst->addSrcEdge(arc.get()); - if (arc->onTree()) + if (arc->onTree()) fn->treeArcs.push_back(std::move(arc)); else fn->arcs.push_back(std::move(arc)); } } else if (tag == GCOV_TAG_LINES && fn) { uint32_t srcNo = buf.getWord(); - if (srcNo >= fn->blocks.size()) { + if (srcNo >= fn->blocks.size()) { errs() << "unexpected block number: " << srcNo << " (in " - << fn->blocks.size() << ")\n"; + << fn->blocks.size() << ")\n"; return false; } - GCOVBlock &Block = *fn->blocks[srcNo]; + GCOVBlock &Block = *fn->blocks[srcNo]; for (;;) { uint32_t line = buf.getWord(); if (line) @@ -273,25 +273,25 @@ bool GCOVFile::readGCDA(GCOVBuffer &buf) { return false; } for (std::unique_ptr<GCOVArc> &arc : fn->arcs) { - if (!buf.readInt64(arc->count)) + if (!buf.readInt64(arc->count)) return false; - arc->src.count += arc->count; + arc->src.count += arc->count; + } + + if (fn->blocks.size() >= 2) { + GCOVBlock &src = *fn->blocks[0]; + GCOVBlock &sink = + Version < GCOV::V408 ? *fn->blocks.back() : *fn->blocks[1]; + auto arc = std::make_unique<GCOVArc>(sink, src, GCOV_ARC_ON_TREE); + sink.addDstEdge(arc.get()); + src.addSrcEdge(arc.get()); + fn->treeArcs.push_back(std::move(arc)); + + for (GCOVBlock &block : fn->blocksRange()) + fn->propagateCounts(block, nullptr); + for (size_t i = fn->treeArcs.size() - 1; i; --i) + fn->treeArcs[i - 1]->src.count += fn->treeArcs[i - 1]->count; } - - if (fn->blocks.size() >= 2) { - GCOVBlock &src = *fn->blocks[0]; - GCOVBlock &sink = - Version < GCOV::V408 ? *fn->blocks.back() : *fn->blocks[1]; - auto arc = std::make_unique<GCOVArc>(sink, src, GCOV_ARC_ON_TREE); - sink.addDstEdge(arc.get()); - src.addSrcEdge(arc.get()); - fn->treeArcs.push_back(std::move(arc)); - - for (GCOVBlock &block : fn->blocksRange()) - fn->propagateCounts(block, nullptr); - for (size_t i = fn->treeArcs.size() - 1; i; --i) - fn->treeArcs[i - 1]->src.count += fn->treeArcs[i - 1]->count; - } } pos += 4 * length; if (pos < buf.cursor.tell()) @@ -312,71 +312,71 @@ void GCOVFile::print(raw_ostream &OS) const { LLVM_DUMP_METHOD void GCOVFile::dump() const { print(dbgs()); } #endif -bool GCOVArc::onTree() const { return flags & GCOV_ARC_ON_TREE; } +bool GCOVArc::onTree() const { return flags & GCOV_ARC_ON_TREE; } //===----------------------------------------------------------------------===// // GCOVFunction implementation. -StringRef GCOVFunction::getName(bool demangle) const { - if (!demangle) - return Name; - if (demangled.empty()) { - do { - if (Name.startswith("_Z")) { - int status = 0; - // Name is guaranteed to be NUL-terminated. - char *res = itaniumDemangle(Name.data(), nullptr, nullptr, &status); - if (status == 0) { - demangled = res; - free(res); - break; - } - } - demangled = Name; - } while (0); - } - return demangled; -} +StringRef GCOVFunction::getName(bool demangle) const { + if (!demangle) + return Name; + if (demangled.empty()) { + do { + if (Name.startswith("_Z")) { + int status = 0; + // Name is guaranteed to be NUL-terminated. + char *res = itaniumDemangle(Name.data(), nullptr, nullptr, &status); + if (status == 0) { + demangled = res; + free(res); + break; + } + } + demangled = Name; + } while (0); + } + return demangled; +} StringRef GCOVFunction::getFilename() const { return file.filenames[srcIdx]; } /// getEntryCount - Get the number of times the function was called by /// retrieving the entry block's count. uint64_t GCOVFunction::getEntryCount() const { - return blocks.front()->getCount(); + return blocks.front()->getCount(); +} + +GCOVBlock &GCOVFunction::getExitBlock() const { + return file.getVersion() < GCOV::V408 ? *blocks.back() : *blocks[1]; } -GCOVBlock &GCOVFunction::getExitBlock() const { - return file.getVersion() < GCOV::V408 ? *blocks.back() : *blocks[1]; +// For each basic block, the sum of incoming edge counts equals the sum of +// outgoing edge counts by Kirchoff's circuit law. If the unmeasured arcs form a +// spanning tree, the count for each unmeasured arc (GCOV_ARC_ON_TREE) can be +// uniquely identified. +uint64_t GCOVFunction::propagateCounts(const GCOVBlock &v, GCOVArc *pred) { + // If GCOV_ARC_ON_TREE edges do form a tree, visited is not needed; otherwise + // this prevents infinite recursion. + if (!visited.insert(&v).second) + return 0; + + uint64_t excess = 0; + for (GCOVArc *e : v.srcs()) + if (e != pred) + excess += e->onTree() ? propagateCounts(e->src, e) : e->count; + for (GCOVArc *e : v.dsts()) + if (e != pred) + excess -= e->onTree() ? propagateCounts(e->dst, e) : e->count; + if (int64_t(excess) < 0) + excess = -excess; + if (pred) + pred->count = excess; + return excess; } -// For each basic block, the sum of incoming edge counts equals the sum of -// outgoing edge counts by Kirchoff's circuit law. If the unmeasured arcs form a -// spanning tree, the count for each unmeasured arc (GCOV_ARC_ON_TREE) can be -// uniquely identified. -uint64_t GCOVFunction::propagateCounts(const GCOVBlock &v, GCOVArc *pred) { - // If GCOV_ARC_ON_TREE edges do form a tree, visited is not needed; otherwise - // this prevents infinite recursion. - if (!visited.insert(&v).second) - return 0; - - uint64_t excess = 0; - for (GCOVArc *e : v.srcs()) - if (e != pred) - excess += e->onTree() ? propagateCounts(e->src, e) : e->count; - for (GCOVArc *e : v.dsts()) - if (e != pred) - excess -= e->onTree() ? propagateCounts(e->dst, e) : e->count; - if (int64_t(excess) < 0) - excess = -excess; - if (pred) - pred->count = excess; - return excess; -} - void GCOVFunction::print(raw_ostream &OS) const { OS << "===== " << Name << " (" << ident << ") @ " << getFilename() << ":" << startLine << "\n"; - for (const auto &Block : blocks) + for (const auto &Block : blocks) Block->print(OS); } @@ -392,25 +392,25 @@ LLVM_DUMP_METHOD void GCOVFunction::dump() const { print(dbgs()); } // GCOVBlock implementation. void GCOVBlock::print(raw_ostream &OS) const { - OS << "Block : " << number << " Counter : " << count << "\n"; + OS << "Block : " << number << " Counter : " << count << "\n"; if (!pred.empty()) { OS << "\tSource Edges : "; for (const GCOVArc *Edge : pred) - OS << Edge->src.number << " (" << Edge->count << "), "; + OS << Edge->src.number << " (" << Edge->count << "), "; OS << "\n"; } if (!succ.empty()) { OS << "\tDestination Edges : "; - for (const GCOVArc *Edge : succ) { - if (Edge->flags & GCOV_ARC_ON_TREE) - OS << '*'; - OS << Edge->dst.number << " (" << Edge->count << "), "; - } + for (const GCOVArc *Edge : succ) { + if (Edge->flags & GCOV_ARC_ON_TREE) + OS << '*'; + OS << Edge->dst.number << " (" << Edge->count << "), "; + } OS << "\n"; } - if (!lines.empty()) { + if (!lines.empty()) { OS << "\tLines : "; - for (uint32_t N : lines) + for (uint32_t N : lines) OS << (N) << ","; OS << "\n"; } @@ -421,96 +421,96 @@ void GCOVBlock::print(raw_ostream &OS) const { LLVM_DUMP_METHOD void GCOVBlock::dump() const { print(dbgs()); } #endif -uint64_t -GCOVBlock::augmentOneCycle(GCOVBlock *src, - std::vector<std::pair<GCOVBlock *, size_t>> &stack) { - GCOVBlock *u; - size_t i; - stack.clear(); - stack.emplace_back(src, 0); - src->incoming = (GCOVArc *)1; // Mark u available for cycle detection - for (;;) { - std::tie(u, i) = stack.back(); - if (i == u->succ.size()) { - u->traversable = false; - stack.pop_back(); - if (stack.empty()) - break; +uint64_t +GCOVBlock::augmentOneCycle(GCOVBlock *src, + std::vector<std::pair<GCOVBlock *, size_t>> &stack) { + GCOVBlock *u; + size_t i; + stack.clear(); + stack.emplace_back(src, 0); + src->incoming = (GCOVArc *)1; // Mark u available for cycle detection + for (;;) { + std::tie(u, i) = stack.back(); + if (i == u->succ.size()) { + u->traversable = false; + stack.pop_back(); + if (stack.empty()) + break; continue; } - ++stack.back().second; - GCOVArc *succ = u->succ[i]; - // Ignore saturated arcs (cycleCount has been reduced to 0) and visited - // blocks. Ignore self arcs to guard against bad input (.gcno has no - // self arcs). - if (succ->cycleCount == 0 || !succ->dst.traversable || &succ->dst == u) - continue; - if (succ->dst.incoming == nullptr) { - succ->dst.incoming = succ; - stack.emplace_back(&succ->dst, 0); - continue; + ++stack.back().second; + GCOVArc *succ = u->succ[i]; + // Ignore saturated arcs (cycleCount has been reduced to 0) and visited + // blocks. Ignore self arcs to guard against bad input (.gcno has no + // self arcs). + if (succ->cycleCount == 0 || !succ->dst.traversable || &succ->dst == u) + continue; + if (succ->dst.incoming == nullptr) { + succ->dst.incoming = succ; + stack.emplace_back(&succ->dst, 0); + continue; + } + uint64_t minCount = succ->cycleCount; + for (GCOVBlock *v = u;;) { + minCount = std::min(minCount, v->incoming->cycleCount); + v = &v->incoming->src; + if (v == &succ->dst) + break; } - uint64_t minCount = succ->cycleCount; - for (GCOVBlock *v = u;;) { - minCount = std::min(minCount, v->incoming->cycleCount); - v = &v->incoming->src; - if (v == &succ->dst) - break; + succ->cycleCount -= minCount; + for (GCOVBlock *v = u;;) { + v->incoming->cycleCount -= minCount; + v = &v->incoming->src; + if (v == &succ->dst) + break; } - succ->cycleCount -= minCount; - for (GCOVBlock *v = u;;) { - v->incoming->cycleCount -= minCount; - v = &v->incoming->src; - if (v == &succ->dst) - break; - } - return minCount; + return minCount; } - return 0; + return 0; } -// Get the total execution count of loops among blocks on the same line. -// Assuming a reducible flow graph, the count is the sum of back edge counts. -// Identifying loops is complex, so we simply find cycles and perform cycle -// cancelling iteratively. -uint64_t GCOVBlock::getCyclesCount(const BlockVector &blocks) { - std::vector<std::pair<GCOVBlock *, size_t>> stack; - uint64_t count = 0, d; - for (;;) { - // Make blocks on the line traversable and try finding a cycle. - for (auto b : blocks) { - const_cast<GCOVBlock *>(b)->traversable = true; - const_cast<GCOVBlock *>(b)->incoming = nullptr; +// Get the total execution count of loops among blocks on the same line. +// Assuming a reducible flow graph, the count is the sum of back edge counts. +// Identifying loops is complex, so we simply find cycles and perform cycle +// cancelling iteratively. +uint64_t GCOVBlock::getCyclesCount(const BlockVector &blocks) { + std::vector<std::pair<GCOVBlock *, size_t>> stack; + uint64_t count = 0, d; + for (;;) { + // Make blocks on the line traversable and try finding a cycle. + for (auto b : blocks) { + const_cast<GCOVBlock *>(b)->traversable = true; + const_cast<GCOVBlock *>(b)->incoming = nullptr; } - d = 0; - for (auto block : blocks) { - auto *b = const_cast<GCOVBlock *>(block); - if (b->traversable && (d = augmentOneCycle(b, stack)) > 0) - break; + d = 0; + for (auto block : blocks) { + auto *b = const_cast<GCOVBlock *>(block); + if (b->traversable && (d = augmentOneCycle(b, stack)) > 0) + break; } - if (d == 0) - break; - count += d; + if (d == 0) + break; + count += d; } - // If there is no more loop, all traversable bits should have been cleared. - // This property is needed by subsequent calls. - for (auto b : blocks) { - assert(!b->traversable); - (void)b; - } - return count; + // If there is no more loop, all traversable bits should have been cleared. + // This property is needed by subsequent calls. + for (auto b : blocks) { + assert(!b->traversable); + (void)b; + } + return count; } //===----------------------------------------------------------------------===// // FileInfo implementation. -// Format dividend/divisor as a percentage. Return 1 if the result is greater -// than 0% and less than 1%. -static uint32_t formatPercentage(uint64_t dividend, uint64_t divisor) { - if (!dividend || !divisor) +// Format dividend/divisor as a percentage. Return 1 if the result is greater +// than 0% and less than 1%. +static uint32_t formatPercentage(uint64_t dividend, uint64_t divisor) { + if (!dividend || !divisor) return 0; - dividend *= 100; - return dividend < divisor ? 1 : dividend / divisor; + dividend *= 100; + return dividend < divisor ? 1 : dividend / divisor; } // This custom division function mimics gcov's branch ouputs: @@ -561,11 +561,11 @@ class LineConsumer { public: LineConsumer() = default; LineConsumer(StringRef Filename) { - // Open source files without requiring a NUL terminator. The concurrent - // modification may nullify the NUL terminator condition. + // Open source files without requiring a NUL terminator. The concurrent + // modification may nullify the NUL terminator condition. ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = - MemoryBuffer::getFileOrSTDIN(Filename, -1, - /*RequiresNullTerminator=*/false); + MemoryBuffer::getFileOrSTDIN(Filename, -1, + /*RequiresNullTerminator=*/false); if (std::error_code EC = BufferOrErr.getError()) { errs() << Filename << ": " << EC.message() << "\n"; Remaining = ""; @@ -621,23 +621,23 @@ static std::string mangleCoveragePath(StringRef Filename, bool PreservePaths) { return std::string(Result.str()); } -std::string Context::getCoveragePath(StringRef filename, - StringRef mainFilename) const { - if (options.NoOutput) +std::string Context::getCoveragePath(StringRef filename, + StringRef mainFilename) const { + if (options.NoOutput) // This is probably a bug in gcov, but when -n is specified, paths aren't // mangled at all, and the -l and -p options are ignored. Here, we do the // same. - return std::string(filename); + return std::string(filename); std::string CoveragePath; - if (options.LongFileNames && !filename.equals(mainFilename)) + if (options.LongFileNames && !filename.equals(mainFilename)) CoveragePath = - mangleCoveragePath(mainFilename, options.PreservePaths) + "##"; - CoveragePath += mangleCoveragePath(filename, options.PreservePaths); - if (options.HashFilenames) { + mangleCoveragePath(mainFilename, options.PreservePaths) + "##"; + CoveragePath += mangleCoveragePath(filename, options.PreservePaths); + if (options.HashFilenames) { MD5 Hasher; MD5::MD5Result Result; - Hasher.update(filename.str()); + Hasher.update(filename.str()); Hasher.final(Result); CoveragePath += "##" + std::string(Result.digest()); } @@ -645,302 +645,302 @@ std::string Context::getCoveragePath(StringRef filename, return CoveragePath; } -void Context::collectFunction(GCOVFunction &f, Summary &summary) { - SourceInfo &si = sources[f.srcIdx]; - if (f.startLine >= si.startLineToFunctions.size()) - si.startLineToFunctions.resize(f.startLine + 1); - si.startLineToFunctions[f.startLine].push_back(&f); - for (const GCOVBlock &b : f.blocksRange()) { - if (b.lines.empty()) - continue; - uint32_t maxLineNum = *std::max_element(b.lines.begin(), b.lines.end()); - if (maxLineNum >= si.lines.size()) - si.lines.resize(maxLineNum + 1); - for (uint32_t lineNum : b.lines) { - LineInfo &line = si.lines[lineNum]; - if (!line.exists) - ++summary.lines; - if (line.count == 0 && b.count) - ++summary.linesExec; - line.exists = true; - line.count += b.count; - line.blocks.push_back(&b); - } +void Context::collectFunction(GCOVFunction &f, Summary &summary) { + SourceInfo &si = sources[f.srcIdx]; + if (f.startLine >= si.startLineToFunctions.size()) + si.startLineToFunctions.resize(f.startLine + 1); + si.startLineToFunctions[f.startLine].push_back(&f); + for (const GCOVBlock &b : f.blocksRange()) { + if (b.lines.empty()) + continue; + uint32_t maxLineNum = *std::max_element(b.lines.begin(), b.lines.end()); + if (maxLineNum >= si.lines.size()) + si.lines.resize(maxLineNum + 1); + for (uint32_t lineNum : b.lines) { + LineInfo &line = si.lines[lineNum]; + if (!line.exists) + ++summary.lines; + if (line.count == 0 && b.count) + ++summary.linesExec; + line.exists = true; + line.count += b.count; + line.blocks.push_back(&b); + } } } -void Context::collectSourceLine(SourceInfo &si, Summary *summary, - LineInfo &line, size_t lineNum) const { - uint64_t count = 0; - for (const GCOVBlock *b : line.blocks) { - if (b->number == 0) { - // For nonstandard control flows, arcs into the exit block may be - // duplicately counted (fork) or not be counted (abnormal exit), and thus - // the (exit,entry) counter may be inaccurate. Count the entry block with - // the outgoing arcs. - for (const GCOVArc *arc : b->succ) - count += arc->count; - } else { - // Add counts from predecessors that are not on the same line. - for (const GCOVArc *arc : b->pred) - if (!llvm::is_contained(line.blocks, &arc->src)) - count += arc->count; - } - for (GCOVArc *arc : b->succ) - arc->cycleCount = arc->count; - } - - count += GCOVBlock::getCyclesCount(line.blocks); - line.count = count; - if (line.exists) { - ++summary->lines; - if (line.count != 0) - ++summary->linesExec; - } - - if (options.BranchInfo) - for (const GCOVBlock *b : line.blocks) { - if (b->getLastLine() != lineNum) - continue; - int branches = 0, execBranches = 0, takenBranches = 0; - for (const GCOVArc *arc : b->succ) { - ++branches; - if (count != 0) - ++execBranches; - if (arc->count != 0) - ++takenBranches; +void Context::collectSourceLine(SourceInfo &si, Summary *summary, + LineInfo &line, size_t lineNum) const { + uint64_t count = 0; + for (const GCOVBlock *b : line.blocks) { + if (b->number == 0) { + // For nonstandard control flows, arcs into the exit block may be + // duplicately counted (fork) or not be counted (abnormal exit), and thus + // the (exit,entry) counter may be inaccurate. Count the entry block with + // the outgoing arcs. + for (const GCOVArc *arc : b->succ) + count += arc->count; + } else { + // Add counts from predecessors that are not on the same line. + for (const GCOVArc *arc : b->pred) + if (!llvm::is_contained(line.blocks, &arc->src)) + count += arc->count; + } + for (GCOVArc *arc : b->succ) + arc->cycleCount = arc->count; + } + + count += GCOVBlock::getCyclesCount(line.blocks); + line.count = count; + if (line.exists) { + ++summary->lines; + if (line.count != 0) + ++summary->linesExec; + } + + if (options.BranchInfo) + for (const GCOVBlock *b : line.blocks) { + if (b->getLastLine() != lineNum) + continue; + int branches = 0, execBranches = 0, takenBranches = 0; + for (const GCOVArc *arc : b->succ) { + ++branches; + if (count != 0) + ++execBranches; + if (arc->count != 0) + ++takenBranches; + } + if (branches > 1) { + summary->branches += branches; + summary->branchesExec += execBranches; + summary->branchesTaken += takenBranches; } - if (branches > 1) { - summary->branches += branches; - summary->branchesExec += execBranches; - summary->branchesTaken += takenBranches; - } - } -} - -void Context::collectSource(SourceInfo &si, Summary &summary) const { - size_t lineNum = 0; - for (LineInfo &line : si.lines) { - collectSourceLine(si, &summary, line, lineNum); - ++lineNum; - } -} - -void Context::annotateSource(SourceInfo &si, const GCOVFile &file, - StringRef gcno, StringRef gcda, - raw_ostream &os) const { - auto source = - options.Intermediate ? LineConsumer() : LineConsumer(si.filename); - - os << " -: 0:Source:" << si.displayName << '\n'; - os << " -: 0:Graph:" << gcno << '\n'; - os << " -: 0:Data:" << gcda << '\n'; - os << " -: 0:Runs:" << file.RunCount << '\n'; - if (file.Version < GCOV::V900) - os << " -: 0:Programs:" << file.ProgramCount << '\n'; - - for (size_t lineNum = 1; !source.empty(); ++lineNum) { - if (lineNum >= si.lines.size()) { - os << " -:"; - source.printNext(os, lineNum); - continue; - } - - const LineInfo &line = si.lines[lineNum]; - if (options.BranchInfo && lineNum < si.startLineToFunctions.size()) - for (const auto *f : si.startLineToFunctions[lineNum]) - printFunctionDetails(*f, os); - if (!line.exists) - os << " -:"; - else if (line.count == 0) - os << " #####:"; - else - os << format("%9" PRIu64 ":", line.count); - source.printNext(os, lineNum); - - uint32_t blockIdx = 0, edgeIdx = 0; - for (const GCOVBlock *b : line.blocks) { - if (b->getLastLine() != lineNum) - continue; - if (options.AllBlocks) { - if (b->getCount() == 0) - os << " $$$$$:"; - else - os << format("%9" PRIu64 ":", b->count); - os << format("%5u-block %2u\n", lineNum, blockIdx++); - } - if (options.BranchInfo) { - size_t NumEdges = b->succ.size(); - if (NumEdges > 1) - printBranchInfo(*b, edgeIdx, os); - else if (options.UncondBranch && NumEdges == 1) { - uint64_t count = b->succ[0]->count; - os << format("unconditional %2u ", edgeIdx++) - << formatBranchInfo(options, count, count) << '\n'; + } +} + +void Context::collectSource(SourceInfo &si, Summary &summary) const { + size_t lineNum = 0; + for (LineInfo &line : si.lines) { + collectSourceLine(si, &summary, line, lineNum); + ++lineNum; + } +} + +void Context::annotateSource(SourceInfo &si, const GCOVFile &file, + StringRef gcno, StringRef gcda, + raw_ostream &os) const { + auto source = + options.Intermediate ? LineConsumer() : LineConsumer(si.filename); + + os << " -: 0:Source:" << si.displayName << '\n'; + os << " -: 0:Graph:" << gcno << '\n'; + os << " -: 0:Data:" << gcda << '\n'; + os << " -: 0:Runs:" << file.RunCount << '\n'; + if (file.Version < GCOV::V900) + os << " -: 0:Programs:" << file.ProgramCount << '\n'; + + for (size_t lineNum = 1; !source.empty(); ++lineNum) { + if (lineNum >= si.lines.size()) { + os << " -:"; + source.printNext(os, lineNum); + continue; + } + + const LineInfo &line = si.lines[lineNum]; + if (options.BranchInfo && lineNum < si.startLineToFunctions.size()) + for (const auto *f : si.startLineToFunctions[lineNum]) + printFunctionDetails(*f, os); + if (!line.exists) + os << " -:"; + else if (line.count == 0) + os << " #####:"; + else + os << format("%9" PRIu64 ":", line.count); + source.printNext(os, lineNum); + + uint32_t blockIdx = 0, edgeIdx = 0; + for (const GCOVBlock *b : line.blocks) { + if (b->getLastLine() != lineNum) + continue; + if (options.AllBlocks) { + if (b->getCount() == 0) + os << " $$$$$:"; + else + os << format("%9" PRIu64 ":", b->count); + os << format("%5u-block %2u\n", lineNum, blockIdx++); + } + if (options.BranchInfo) { + size_t NumEdges = b->succ.size(); + if (NumEdges > 1) + printBranchInfo(*b, edgeIdx, os); + else if (options.UncondBranch && NumEdges == 1) { + uint64_t count = b->succ[0]->count; + os << format("unconditional %2u ", edgeIdx++) + << formatBranchInfo(options, count, count) << '\n'; } } } } -} - -void Context::printSourceToIntermediate(const SourceInfo &si, - raw_ostream &os) const { - os << "file:" << si.filename << '\n'; - for (const auto &fs : si.startLineToFunctions) - for (const GCOVFunction *f : fs) - os << "function:" << f->startLine << ',' << f->getEntryCount() << ',' - << f->getName(options.Demangle) << '\n'; - for (size_t lineNum = 1, size = si.lines.size(); lineNum < size; ++lineNum) { - const LineInfo &line = si.lines[lineNum]; - if (line.blocks.empty()) - continue; - // GCC 8 (r254259) added third third field for Ada: - // lcount:<line>,<count>,<has_unexecuted_blocks> - // We don't need the third field. - os << "lcount:" << lineNum << ',' << line.count << '\n'; - - if (!options.BranchInfo) - continue; - for (const GCOVBlock *b : line.blocks) { - if (b->succ.size() < 2 || b->getLastLine() != lineNum) - continue; - for (const GCOVArc *arc : b->succ) { - const char *type = - b->getCount() ? arc->count ? "taken" : "nottaken" : "notexec"; - os << "branch:" << lineNum << ',' << type << '\n'; +} + +void Context::printSourceToIntermediate(const SourceInfo &si, + raw_ostream &os) const { + os << "file:" << si.filename << '\n'; + for (const auto &fs : si.startLineToFunctions) + for (const GCOVFunction *f : fs) + os << "function:" << f->startLine << ',' << f->getEntryCount() << ',' + << f->getName(options.Demangle) << '\n'; + for (size_t lineNum = 1, size = si.lines.size(); lineNum < size; ++lineNum) { + const LineInfo &line = si.lines[lineNum]; + if (line.blocks.empty()) + continue; + // GCC 8 (r254259) added third third field for Ada: + // lcount:<line>,<count>,<has_unexecuted_blocks> + // We don't need the third field. + os << "lcount:" << lineNum << ',' << line.count << '\n'; + + if (!options.BranchInfo) + continue; + for (const GCOVBlock *b : line.blocks) { + if (b->succ.size() < 2 || b->getLastLine() != lineNum) + continue; + for (const GCOVArc *arc : b->succ) { + const char *type = + b->getCount() ? arc->count ? "taken" : "nottaken" : "notexec"; + os << "branch:" << lineNum << ',' << type << '\n'; } } } -} - -void Context::print(StringRef filename, StringRef gcno, StringRef gcda, - GCOVFile &file) { - for (StringRef filename : file.filenames) { - sources.emplace_back(filename); - SourceInfo &si = sources.back(); - si.displayName = si.filename; - if (!options.SourcePrefix.empty() && - sys::path::replace_path_prefix(si.displayName, options.SourcePrefix, - "") && - !si.displayName.empty()) { - // TODO replace_path_prefix may strip the prefix even if the remaining - // part does not start with a separator. - if (sys::path::is_separator(si.displayName[0])) - si.displayName.erase(si.displayName.begin()); - else - si.displayName = si.filename; - } - if (options.RelativeOnly && sys::path::is_absolute(si.displayName)) - si.ignored = true; +} + +void Context::print(StringRef filename, StringRef gcno, StringRef gcda, + GCOVFile &file) { + for (StringRef filename : file.filenames) { + sources.emplace_back(filename); + SourceInfo &si = sources.back(); + si.displayName = si.filename; + if (!options.SourcePrefix.empty() && + sys::path::replace_path_prefix(si.displayName, options.SourcePrefix, + "") && + !si.displayName.empty()) { + // TODO replace_path_prefix may strip the prefix even if the remaining + // part does not start with a separator. + if (sys::path::is_separator(si.displayName[0])) + si.displayName.erase(si.displayName.begin()); + else + si.displayName = si.filename; + } + if (options.RelativeOnly && sys::path::is_absolute(si.displayName)) + si.ignored = true; } - raw_ostream &os = llvm::outs(); - for (GCOVFunction &f : make_pointee_range(file.functions)) { - Summary summary(f.getName(options.Demangle)); - collectFunction(f, summary); - if (options.FuncCoverage && !options.UseStdout) { - os << "Function '" << summary.Name << "'\n"; - printSummary(summary, os); - os << '\n'; - } + raw_ostream &os = llvm::outs(); + for (GCOVFunction &f : make_pointee_range(file.functions)) { + Summary summary(f.getName(options.Demangle)); + collectFunction(f, summary); + if (options.FuncCoverage && !options.UseStdout) { + os << "Function '" << summary.Name << "'\n"; + printSummary(summary, os); + os << '\n'; + } } - for (SourceInfo &si : sources) { - if (si.ignored) - continue; - Summary summary(si.displayName); - collectSource(si, summary); - - // Print file summary unless -t is specified. - std::string gcovName = getCoveragePath(si.filename, filename); - if (!options.UseStdout) { - os << "File '" << summary.Name << "'\n"; - printSummary(summary, os); - if (!options.NoOutput && !options.Intermediate) - os << "Creating '" << gcovName << "'\n"; - os << '\n'; - } - - if (options.NoOutput || options.Intermediate) - continue; - Optional<raw_fd_ostream> os; - if (!options.UseStdout) { - std::error_code ec; - os.emplace(gcovName, ec, sys::fs::OF_Text); - if (ec) { - errs() << ec.message() << '\n'; - continue; - } + for (SourceInfo &si : sources) { + if (si.ignored) + continue; + Summary summary(si.displayName); + collectSource(si, summary); + + // Print file summary unless -t is specified. + std::string gcovName = getCoveragePath(si.filename, filename); + if (!options.UseStdout) { + os << "File '" << summary.Name << "'\n"; + printSummary(summary, os); + if (!options.NoOutput && !options.Intermediate) + os << "Creating '" << gcovName << "'\n"; + os << '\n'; } - annotateSource(si, file, gcno, gcda, - options.UseStdout ? llvm::outs() : *os); + + if (options.NoOutput || options.Intermediate) + continue; + Optional<raw_fd_ostream> os; + if (!options.UseStdout) { + std::error_code ec; + os.emplace(gcovName, ec, sys::fs::OF_Text); + if (ec) { + errs() << ec.message() << '\n'; + continue; + } + } + annotateSource(si, file, gcno, gcda, + options.UseStdout ? llvm::outs() : *os); + } + + if (options.Intermediate && !options.NoOutput) { + // gcov 7.* unexpectedly create multiple .gcov files, which was fixed in 8.0 + // (PR GCC/82702). We create just one file. + std::string outputPath(sys::path::filename(filename)); + std::error_code ec; + raw_fd_ostream os(outputPath + ".gcov", ec, sys::fs::OF_Text); + if (ec) { + errs() << ec.message() << '\n'; + return; + } + + for (const SourceInfo &si : sources) + printSourceToIntermediate(si, os); } +} - if (options.Intermediate && !options.NoOutput) { - // gcov 7.* unexpectedly create multiple .gcov files, which was fixed in 8.0 - // (PR GCC/82702). We create just one file. - std::string outputPath(sys::path::filename(filename)); - std::error_code ec; - raw_fd_ostream os(outputPath + ".gcov", ec, sys::fs::OF_Text); - if (ec) { - errs() << ec.message() << '\n'; - return; - } - - for (const SourceInfo &si : sources) - printSourceToIntermediate(si, os); - } +void Context::printFunctionDetails(const GCOVFunction &f, + raw_ostream &os) const { + const uint64_t entryCount = f.getEntryCount(); + uint32_t blocksExec = 0; + const GCOVBlock &exitBlock = f.getExitBlock(); + uint64_t exitCount = 0; + for (const GCOVArc *arc : exitBlock.pred) + exitCount += arc->count; + for (const GCOVBlock &b : f.blocksRange()) + if (b.number != 0 && &b != &exitBlock && b.getCount()) + ++blocksExec; + + os << "function " << f.getName(options.Demangle) << " called " << entryCount + << " returned " << formatPercentage(exitCount, entryCount) + << "% blocks executed " + << formatPercentage(blocksExec, f.blocks.size() - 2) << "%\n"; } -void Context::printFunctionDetails(const GCOVFunction &f, - raw_ostream &os) const { - const uint64_t entryCount = f.getEntryCount(); - uint32_t blocksExec = 0; - const GCOVBlock &exitBlock = f.getExitBlock(); - uint64_t exitCount = 0; - for (const GCOVArc *arc : exitBlock.pred) - exitCount += arc->count; - for (const GCOVBlock &b : f.blocksRange()) - if (b.number != 0 && &b != &exitBlock && b.getCount()) - ++blocksExec; - - os << "function " << f.getName(options.Demangle) << " called " << entryCount - << " returned " << formatPercentage(exitCount, entryCount) - << "% blocks executed " - << formatPercentage(blocksExec, f.blocks.size() - 2) << "%\n"; +/// printBranchInfo - Print conditional branch probabilities. +void Context::printBranchInfo(const GCOVBlock &Block, uint32_t &edgeIdx, + raw_ostream &os) const { + uint64_t total = 0; + for (const GCOVArc *arc : Block.dsts()) + total += arc->count; + for (const GCOVArc *arc : Block.dsts()) + os << format("branch %2u ", edgeIdx++) + << formatBranchInfo(options, arc->count, total) << '\n'; } -/// printBranchInfo - Print conditional branch probabilities. -void Context::printBranchInfo(const GCOVBlock &Block, uint32_t &edgeIdx, - raw_ostream &os) const { - uint64_t total = 0; - for (const GCOVArc *arc : Block.dsts()) - total += arc->count; - for (const GCOVArc *arc : Block.dsts()) - os << format("branch %2u ", edgeIdx++) - << formatBranchInfo(options, arc->count, total) << '\n'; -} - -void Context::printSummary(const Summary &summary, raw_ostream &os) const { - os << format("Lines executed:%.2f%% of %" PRIu64 "\n", - double(summary.linesExec) * 100 / summary.lines, summary.lines); - if (options.BranchInfo) { - if (summary.branches == 0) { - os << "No branches\n"; +void Context::printSummary(const Summary &summary, raw_ostream &os) const { + os << format("Lines executed:%.2f%% of %" PRIu64 "\n", + double(summary.linesExec) * 100 / summary.lines, summary.lines); + if (options.BranchInfo) { + if (summary.branches == 0) { + os << "No branches\n"; } else { - os << format("Branches executed:%.2f%% of %" PRIu64 "\n", - double(summary.branchesExec) * 100 / summary.branches, - summary.branches); - os << format("Taken at least once:%.2f%% of %" PRIu64 "\n", - double(summary.branchesTaken) * 100 / summary.branches, - summary.branches); + os << format("Branches executed:%.2f%% of %" PRIu64 "\n", + double(summary.branchesExec) * 100 / summary.branches, + summary.branches); + os << format("Taken at least once:%.2f%% of %" PRIu64 "\n", + double(summary.branchesTaken) * 100 / summary.branches, + summary.branches); } - os << "No calls\n"; + os << "No calls\n"; } } -void llvm::gcovOneInput(const GCOV::Options &options, StringRef filename, - StringRef gcno, StringRef gcda, GCOVFile &file) { - Context fi(options); - fi.print(filename, gcno, gcda, file); +void llvm::gcovOneInput(const GCOV::Options &options, StringRef filename, + StringRef gcno, StringRef gcda, GCOVFile &file) { + Context fi(options); + fi.print(filename, gcno, gcda, file); } diff --git a/contrib/libs/llvm12/lib/ProfileData/InstrProf.cpp b/contrib/libs/llvm12/lib/ProfileData/InstrProf.cpp index 167ce44cc4..4a0cee6708 100644 --- a/contrib/libs/llvm12/lib/ProfileData/InstrProf.cpp +++ b/contrib/libs/llvm12/lib/ProfileData/InstrProf.cpp @@ -625,11 +625,11 @@ void InstrProfValueSiteRecord::merge(InstrProfValueSiteRecord &Input, } } -void InstrProfValueSiteRecord::scale(uint64_t N, uint64_t D, +void InstrProfValueSiteRecord::scale(uint64_t N, uint64_t D, function_ref<void(instrprof_error)> Warn) { for (auto I = ValueData.begin(), IE = ValueData.end(); I != IE; ++I) { bool Overflowed; - I->Count = SaturatingMultiply(I->Count, N, &Overflowed) / D; + I->Count = SaturatingMultiply(I->Count, N, &Overflowed) / D; if (Overflowed) Warn(instrprof_error::counter_overflow); } @@ -678,23 +678,23 @@ void InstrProfRecord::merge(InstrProfRecord &Other, uint64_t Weight, } void InstrProfRecord::scaleValueProfData( - uint32_t ValueKind, uint64_t N, uint64_t D, + uint32_t ValueKind, uint64_t N, uint64_t D, function_ref<void(instrprof_error)> Warn) { for (auto &R : getValueSitesForKind(ValueKind)) - R.scale(N, D, Warn); + R.scale(N, D, Warn); } -void InstrProfRecord::scale(uint64_t N, uint64_t D, +void InstrProfRecord::scale(uint64_t N, uint64_t D, function_ref<void(instrprof_error)> Warn) { - assert(D != 0 && "D cannot be 0"); + assert(D != 0 && "D cannot be 0"); for (auto &Count : this->Counts) { bool Overflowed; - Count = SaturatingMultiply(Count, N, &Overflowed) / D; + Count = SaturatingMultiply(Count, N, &Overflowed) / D; if (Overflowed) Warn(instrprof_error::counter_overflow); } for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) - scaleValueProfData(Kind, N, D, Warn); + scaleValueProfData(Kind, N, D, Warn); } // Map indirect call target name hash to name string. @@ -1114,15 +1114,15 @@ bool canRenameComdatFunc(const Function &F, bool CheckAddressTaken) { // Create a COMDAT variable INSTR_PROF_RAW_VERSION_VAR to make the runtime // aware this is an ir_level profile so it can set the version flag. -void createIRLevelProfileFlagVar(Module &M, bool IsCS, - bool InstrEntryBBEnabled) { +void createIRLevelProfileFlagVar(Module &M, bool IsCS, + bool InstrEntryBBEnabled) { const StringRef VarName(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR)); Type *IntTy64 = Type::getInt64Ty(M.getContext()); uint64_t ProfileVersion = (INSTR_PROF_RAW_VERSION | VARIANT_MASK_IR_PROF); if (IsCS) ProfileVersion |= VARIANT_MASK_CSIR_PROF; - if (InstrEntryBBEnabled) - ProfileVersion |= VARIANT_MASK_INSTR_ENTRY; + if (InstrEntryBBEnabled) + ProfileVersion |= VARIANT_MASK_INSTR_ENTRY; auto IRLevelVersionVariable = new GlobalVariable( M, IntTy64, true, GlobalValue::WeakAnyLinkage, Constant::getIntegerValue(IntTy64, APInt(64, ProfileVersion)), VarName); diff --git a/contrib/libs/llvm12/lib/ProfileData/InstrProfReader.cpp b/contrib/libs/llvm12/lib/ProfileData/InstrProfReader.cpp index 665df44249..9581e5b486 100644 --- a/contrib/libs/llvm12/lib/ProfileData/InstrProfReader.cpp +++ b/contrib/libs/llvm12/lib/ProfileData/InstrProfReader.cpp @@ -154,29 +154,29 @@ bool TextInstrProfReader::hasFormat(const MemoryBuffer &Buffer) { Error TextInstrProfReader::readHeader() { Symtab.reset(new InstrProfSymtab()); bool IsIRInstr = false; - bool IsEntryFirst = false; - bool IsCS = false; - - while (Line->startswith(":")) { - StringRef Str = Line->substr(1); - if (Str.equals_lower("ir")) - IsIRInstr = true; - else if (Str.equals_lower("fe")) - IsIRInstr = false; - else if (Str.equals_lower("csir")) { - IsIRInstr = true; - IsCS = true; - } else if (Str.equals_lower("entry_first")) - IsEntryFirst = true; - else if (Str.equals_lower("not_entry_first")) - IsEntryFirst = false; - else - return error(instrprof_error::bad_header); - ++Line; + bool IsEntryFirst = false; + bool IsCS = false; + + while (Line->startswith(":")) { + StringRef Str = Line->substr(1); + if (Str.equals_lower("ir")) + IsIRInstr = true; + else if (Str.equals_lower("fe")) + IsIRInstr = false; + else if (Str.equals_lower("csir")) { + IsIRInstr = true; + IsCS = true; + } else if (Str.equals_lower("entry_first")) + IsEntryFirst = true; + else if (Str.equals_lower("not_entry_first")) + IsEntryFirst = false; + else + return error(instrprof_error::bad_header); + ++Line; } IsIRLevelProfile = IsIRInstr; - InstrEntryBBEnabled = IsEntryFirst; - HasCSIRLevelProfile = IsCS; + InstrEntryBBEnabled = IsEntryFirst; + HasCSIRLevelProfile = IsCS; return success(); } diff --git a/contrib/libs/llvm12/lib/ProfileData/InstrProfWriter.cpp b/contrib/libs/llvm12/lib/ProfileData/InstrProfWriter.cpp index aa1fe31ccc..d076683223 100644 --- a/contrib/libs/llvm12/lib/ProfileData/InstrProfWriter.cpp +++ b/contrib/libs/llvm12/lib/ProfileData/InstrProfWriter.cpp @@ -165,9 +165,9 @@ public: } // end namespace llvm -InstrProfWriter::InstrProfWriter(bool Sparse, bool InstrEntryBBEnabled) - : Sparse(Sparse), InstrEntryBBEnabled(InstrEntryBBEnabled), - InfoObj(new InstrProfRecordWriterTrait()) {} +InstrProfWriter::InstrProfWriter(bool Sparse, bool InstrEntryBBEnabled) + : Sparse(Sparse), InstrEntryBBEnabled(InstrEntryBBEnabled), + InfoObj(new InstrProfRecordWriterTrait()) {} InstrProfWriter::~InstrProfWriter() { delete InfoObj; } @@ -241,7 +241,7 @@ void InstrProfWriter::addRecord(StringRef Name, uint64_t Hash, // We've never seen a function with this name and hash, add it. Dest = std::move(I); if (Weight > 1) - Dest.scale(Weight, 1, MapWarn); + Dest.scale(Weight, 1, MapWarn); } else { // We're updating a function we've seen before. Dest.merge(I, Weight, MapWarn); @@ -309,9 +309,9 @@ void InstrProfWriter::writeImpl(ProfOStream &OS) { Header.Version |= VARIANT_MASK_IR_PROF; Header.Version |= VARIANT_MASK_CSIR_PROF; } - if (InstrEntryBBEnabled) - Header.Version |= VARIANT_MASK_INSTR_ENTRY; - + if (InstrEntryBBEnabled) + Header.Version |= VARIANT_MASK_INSTR_ENTRY; + Header.Unused = 0; Header.HashType = static_cast<uint64_t>(IndexedInstrProf::HashType); Header.HashOffset = 0; @@ -445,8 +445,8 @@ Error InstrProfWriter::writeText(raw_fd_ostream &OS) { OS << "# IR level Instrumentation Flag\n:ir\n"; else if (ProfileKind == PF_IRLevelWithCS) OS << "# CSIR level Instrumentation Flag\n:csir\n"; - if (InstrEntryBBEnabled) - OS << "# Always instrument the function entry block\n:entry_first\n"; + if (InstrEntryBBEnabled) + OS << "# Always instrument the function entry block\n:entry_first\n"; InstrProfSymtab Symtab; using FuncPair = detail::DenseMapPair<uint64_t, InstrProfRecord>; diff --git a/contrib/libs/llvm12/lib/ProfileData/ProfileSummaryBuilder.cpp b/contrib/libs/llvm12/lib/ProfileData/ProfileSummaryBuilder.cpp index 0f1e6d1a65..0e03aa5017 100644 --- a/contrib/libs/llvm12/lib/ProfileData/ProfileSummaryBuilder.cpp +++ b/contrib/libs/llvm12/lib/ProfileData/ProfileSummaryBuilder.cpp @@ -18,14 +18,14 @@ #include "llvm/ProfileData/ProfileCommon.h" #include "llvm/ProfileData/SampleProf.h" #include "llvm/Support/Casting.h" -#include "llvm/Support/CommandLine.h" +#include "llvm/Support/CommandLine.h" using namespace llvm; -cl::opt<bool> UseContextLessSummary( - "profile-summary-contextless", cl::Hidden, cl::init(false), cl::ZeroOrMore, - cl::desc("Merge context profiles before calculating thresholds.")); - +cl::opt<bool> UseContextLessSummary( + "profile-summary-contextless", cl::Hidden, cl::init(false), cl::ZeroOrMore, + cl::desc("Merge context profiles before calculating thresholds.")); + // A set of cutoff values. Each value, when divided by ProfileSummary::Scale // (which is 1000000) is a desired percentile of total counts. static const uint32_t DefaultCutoffsData[] = { @@ -116,35 +116,35 @@ std::unique_ptr<ProfileSummary> SampleProfileSummaryBuilder::getSummary() { MaxFunctionCount, NumCounts, NumFunctions); } -std::unique_ptr<ProfileSummary> -SampleProfileSummaryBuilder::computeSummaryForProfiles( - const StringMap<sampleprof::FunctionSamples> &Profiles) { - assert(NumFunctions == 0 && - "This can only be called on an empty summary builder"); - StringMap<sampleprof::FunctionSamples> ContextLessProfiles; - const StringMap<sampleprof::FunctionSamples> *ProfilesToUse = &Profiles; - // For CSSPGO, context-sensitive profile effectively split a function profile - // into many copies each representing the CFG profile of a particular calling - // context. That makes the count distribution looks more flat as we now have - // more function profiles each with lower counts, which in turn leads to lower - // hot thresholds. To compensate for that, by defauly we merge context - // profiles before coumputing profile summary. - if (UseContextLessSummary || (sampleprof::FunctionSamples::ProfileIsCS && - !UseContextLessSummary.getNumOccurrences())) { - for (const auto &I : Profiles) { - ContextLessProfiles[I.second.getName()].merge(I.second); - } - ProfilesToUse = &ContextLessProfiles; - } - - for (const auto &I : *ProfilesToUse) { - const sampleprof::FunctionSamples &Profile = I.second; - addRecord(Profile); - } - - return getSummary(); -} - +std::unique_ptr<ProfileSummary> +SampleProfileSummaryBuilder::computeSummaryForProfiles( + const StringMap<sampleprof::FunctionSamples> &Profiles) { + assert(NumFunctions == 0 && + "This can only be called on an empty summary builder"); + StringMap<sampleprof::FunctionSamples> ContextLessProfiles; + const StringMap<sampleprof::FunctionSamples> *ProfilesToUse = &Profiles; + // For CSSPGO, context-sensitive profile effectively split a function profile + // into many copies each representing the CFG profile of a particular calling + // context. That makes the count distribution looks more flat as we now have + // more function profiles each with lower counts, which in turn leads to lower + // hot thresholds. To compensate for that, by defauly we merge context + // profiles before coumputing profile summary. + if (UseContextLessSummary || (sampleprof::FunctionSamples::ProfileIsCS && + !UseContextLessSummary.getNumOccurrences())) { + for (const auto &I : Profiles) { + ContextLessProfiles[I.second.getName()].merge(I.second); + } + ProfilesToUse = &ContextLessProfiles; + } + + for (const auto &I : *ProfilesToUse) { + const sampleprof::FunctionSamples &Profile = I.second; + addRecord(Profile); + } + + return getSummary(); +} + std::unique_ptr<ProfileSummary> InstrProfSummaryBuilder::getSummary() { computeDetailedSummary(); return std::make_unique<ProfileSummary>( @@ -153,22 +153,22 @@ std::unique_ptr<ProfileSummary> InstrProfSummaryBuilder::getSummary() { } void InstrProfSummaryBuilder::addEntryCount(uint64_t Count) { - NumFunctions++; - - // Skip invalid count. - if (Count == (uint64_t)-1) - return; - + NumFunctions++; + + // Skip invalid count. + if (Count == (uint64_t)-1) + return; + addCount(Count); if (Count > MaxFunctionCount) MaxFunctionCount = Count; } void InstrProfSummaryBuilder::addInternalCount(uint64_t Count) { - // Skip invalid count. - if (Count == (uint64_t)-1) - return; - + // Skip invalid count. + if (Count == (uint64_t)-1) + return; + addCount(Count); if (Count > MaxInternalBlockCount) MaxInternalBlockCount = Count; diff --git a/contrib/libs/llvm12/lib/ProfileData/SampleProf.cpp b/contrib/libs/llvm12/lib/ProfileData/SampleProf.cpp index 669976d795..d6acc00e1a 100644 --- a/contrib/libs/llvm12/lib/ProfileData/SampleProf.cpp +++ b/contrib/libs/llvm12/lib/ProfileData/SampleProf.cpp @@ -14,8 +14,8 @@ #include "llvm/ProfileData/SampleProf.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/DebugInfoMetadata.h" -#include "llvm/IR/PseudoProbe.h" -#include "llvm/ProfileData/SampleProfReader.h" +#include "llvm/IR/PseudoProbe.h" +#include "llvm/ProfileData/SampleProfReader.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Error.h" @@ -32,8 +32,8 @@ using namespace sampleprof; namespace llvm { namespace sampleprof { SampleProfileFormat FunctionSamples::Format; -bool FunctionSamples::ProfileIsProbeBased = false; -bool FunctionSamples::ProfileIsCS = false; +bool FunctionSamples::ProfileIsProbeBased = false; +bool FunctionSamples::ProfileIsCS = false; bool FunctionSamples::UseMD5; } // namespace sampleprof } // namespace llvm @@ -79,8 +79,8 @@ class SampleProfErrorCategoryType : public std::error_category { return "Uncompress failure"; case sampleprof_error::zlib_unavailable: return "Zlib is unavailable"; - case sampleprof_error::hash_mismatch: - return "Function hash mismatch"; + case sampleprof_error::hash_mismatch: + return "Function hash mismatch"; } llvm_unreachable("A value of sampleprof_error has no message."); } @@ -133,9 +133,9 @@ raw_ostream &llvm::sampleprof::operator<<(raw_ostream &OS, /// Print the samples collected for a function on stream \p OS. void FunctionSamples::print(raw_ostream &OS, unsigned Indent) const { - if (getFunctionHash()) - OS << "CFG checksum " << getFunctionHash() << "\n"; - + if (getFunctionHash()) + OS << "CFG checksum " << getFunctionHash() << "\n"; + OS << TotalSamples << ", " << TotalHeadSamples << ", " << BodySamples.size() << " sampled lines\n"; @@ -183,22 +183,22 @@ unsigned FunctionSamples::getOffset(const DILocation *DIL) { 0xffff; } -LineLocation FunctionSamples::getCallSiteIdentifier(const DILocation *DIL) { - if (FunctionSamples::ProfileIsProbeBased) - // In a pseudo-probe based profile, a callsite is simply represented by the - // ID of the probe associated with the call instruction. The probe ID is - // encoded in the Discriminator field of the call instruction's debug - // metadata. - return LineLocation(PseudoProbeDwarfDiscriminator::extractProbeIndex( - DIL->getDiscriminator()), - 0); - else - return LineLocation(FunctionSamples::getOffset(DIL), - DIL->getBaseDiscriminator()); -} - -const FunctionSamples *FunctionSamples::findFunctionSamples( - const DILocation *DIL, SampleProfileReaderItaniumRemapper *Remapper) const { +LineLocation FunctionSamples::getCallSiteIdentifier(const DILocation *DIL) { + if (FunctionSamples::ProfileIsProbeBased) + // In a pseudo-probe based profile, a callsite is simply represented by the + // ID of the probe associated with the call instruction. The probe ID is + // encoded in the Discriminator field of the call instruction's debug + // metadata. + return LineLocation(PseudoProbeDwarfDiscriminator::extractProbeIndex( + DIL->getDiscriminator()), + 0); + else + return LineLocation(FunctionSamples::getOffset(DIL), + DIL->getBaseDiscriminator()); +} + +const FunctionSamples *FunctionSamples::findFunctionSamples( + const DILocation *DIL, SampleProfileReaderItaniumRemapper *Remapper) const { assert(DIL); SmallVector<std::pair<LineLocation, StringRef>, 10> S; @@ -213,59 +213,59 @@ const FunctionSamples *FunctionSamples::findFunctionSamples( return this; const FunctionSamples *FS = this; for (int i = S.size() - 1; i >= 0 && FS != nullptr; i--) { - FS = FS->findFunctionSamplesAt(S[i].first, S[i].second, Remapper); + FS = FS->findFunctionSamplesAt(S[i].first, S[i].second, Remapper); } return FS; } -void FunctionSamples::findAllNames(DenseSet<StringRef> &NameSet) const { - NameSet.insert(Name); - for (const auto &BS : BodySamples) - for (const auto &TS : BS.second.getCallTargets()) - NameSet.insert(TS.getKey()); - - for (const auto &CS : CallsiteSamples) { - for (const auto &NameFS : CS.second) { - NameSet.insert(NameFS.first); - NameFS.second.findAllNames(NameSet); - } - } -} - -const FunctionSamples *FunctionSamples::findFunctionSamplesAt( - const LineLocation &Loc, StringRef CalleeName, - SampleProfileReaderItaniumRemapper *Remapper) const { - std::string CalleeGUID; - CalleeName = getRepInFormat(CalleeName, UseMD5, CalleeGUID); - - auto iter = CallsiteSamples.find(Loc); - if (iter == CallsiteSamples.end()) - return nullptr; - auto FS = iter->second.find(CalleeName); - if (FS != iter->second.end()) - return &FS->second; - if (Remapper) { - if (auto NameInProfile = Remapper->lookUpNameInProfile(CalleeName)) { - auto FS = iter->second.find(*NameInProfile); - if (FS != iter->second.end()) - return &FS->second; - } - } - // If we cannot find exact match of the callee name, return the FS with - // the max total count. Only do this when CalleeName is not provided, - // i.e., only for indirect calls. - if (!CalleeName.empty()) - return nullptr; - uint64_t MaxTotalSamples = 0; - const FunctionSamples *R = nullptr; - for (const auto &NameFS : iter->second) - if (NameFS.second.getTotalSamples() >= MaxTotalSamples) { - MaxTotalSamples = NameFS.second.getTotalSamples(); - R = &NameFS.second; - } - return R; -} - +void FunctionSamples::findAllNames(DenseSet<StringRef> &NameSet) const { + NameSet.insert(Name); + for (const auto &BS : BodySamples) + for (const auto &TS : BS.second.getCallTargets()) + NameSet.insert(TS.getKey()); + + for (const auto &CS : CallsiteSamples) { + for (const auto &NameFS : CS.second) { + NameSet.insert(NameFS.first); + NameFS.second.findAllNames(NameSet); + } + } +} + +const FunctionSamples *FunctionSamples::findFunctionSamplesAt( + const LineLocation &Loc, StringRef CalleeName, + SampleProfileReaderItaniumRemapper *Remapper) const { + std::string CalleeGUID; + CalleeName = getRepInFormat(CalleeName, UseMD5, CalleeGUID); + + auto iter = CallsiteSamples.find(Loc); + if (iter == CallsiteSamples.end()) + return nullptr; + auto FS = iter->second.find(CalleeName); + if (FS != iter->second.end()) + return &FS->second; + if (Remapper) { + if (auto NameInProfile = Remapper->lookUpNameInProfile(CalleeName)) { + auto FS = iter->second.find(*NameInProfile); + if (FS != iter->second.end()) + return &FS->second; + } + } + // If we cannot find exact match of the callee name, return the FS with + // the max total count. Only do this when CalleeName is not provided, + // i.e., only for indirect calls. + if (!CalleeName.empty()) + return nullptr; + uint64_t MaxTotalSamples = 0; + const FunctionSamples *R = nullptr; + for (const auto &NameFS : iter->second) + if (NameFS.second.getTotalSamples() >= MaxTotalSamples) { + MaxTotalSamples = NameFS.second.getTotalSamples(); + R = &NameFS.second; + } + return R; +} + #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void FunctionSamples::dump() const { print(dbgs(), 0); } #endif @@ -287,7 +287,7 @@ std::error_code ProfileSymbolList::read(const uint8_t *Data, std::error_code ProfileSymbolList::write(raw_ostream &OS) { // Sort the symbols before output. If doing compression. // It will make the compression much more effective. - std::vector<StringRef> SortedList(Syms.begin(), Syms.end()); + std::vector<StringRef> SortedList(Syms.begin(), Syms.end()); llvm::sort(SortedList); std::string OutputString; @@ -302,7 +302,7 @@ std::error_code ProfileSymbolList::write(raw_ostream &OS) { void ProfileSymbolList::dump(raw_ostream &OS) const { OS << "======== Dump profile symbol list ========\n"; - std::vector<StringRef> SortedList(Syms.begin(), Syms.end()); + std::vector<StringRef> SortedList(Syms.begin(), Syms.end()); llvm::sort(SortedList); for (auto &Sym : SortedList) diff --git a/contrib/libs/llvm12/lib/ProfileData/SampleProfReader.cpp b/contrib/libs/llvm12/lib/ProfileData/SampleProfReader.cpp index ba9d456097..38cbca844c 100644 --- a/contrib/libs/llvm12/lib/ProfileData/SampleProfReader.cpp +++ b/contrib/libs/llvm12/lib/ProfileData/SampleProfReader.cpp @@ -83,52 +83,52 @@ static bool ParseHead(const StringRef &Input, StringRef &FName, /// Returns true if line offset \p L is legal (only has 16 bits). static bool isOffsetLegal(unsigned L) { return (L & 0xffff) == L; } -/// Parse \p Input that contains metadata. -/// Possible metadata: -/// - CFG Checksum information: -/// !CFGChecksum: 12345 -/// Stores the FunctionHash (a.k.a. CFG Checksum) into \p FunctionHash. -static bool parseMetadata(const StringRef &Input, uint64_t &FunctionHash) { - if (!Input.startswith("!CFGChecksum:")) - return false; - - StringRef CFGInfo = Input.substr(strlen("!CFGChecksum:")).trim(); - return !CFGInfo.getAsInteger(10, FunctionHash); -} - -enum class LineType { - CallSiteProfile, - BodyProfile, - Metadata, -}; - +/// Parse \p Input that contains metadata. +/// Possible metadata: +/// - CFG Checksum information: +/// !CFGChecksum: 12345 +/// Stores the FunctionHash (a.k.a. CFG Checksum) into \p FunctionHash. +static bool parseMetadata(const StringRef &Input, uint64_t &FunctionHash) { + if (!Input.startswith("!CFGChecksum:")) + return false; + + StringRef CFGInfo = Input.substr(strlen("!CFGChecksum:")).trim(); + return !CFGInfo.getAsInteger(10, FunctionHash); +} + +enum class LineType { + CallSiteProfile, + BodyProfile, + Metadata, +}; + /// Parse \p Input as line sample. /// /// \param Input input line. -/// \param LineTy Type of this line. +/// \param LineTy Type of this line. /// \param Depth the depth of the inline stack. /// \param NumSamples total samples of the line/inlined callsite. /// \param LineOffset line offset to the start of the function. /// \param Discriminator discriminator of the line. /// \param TargetCountMap map from indirect call target to count. -/// \param FunctionHash the function's CFG hash, used by pseudo probe. +/// \param FunctionHash the function's CFG hash, used by pseudo probe. /// /// returns true if parsing is successful. -static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth, +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, - uint64_t &FunctionHash) { + DenseMap<StringRef, uint64_t> &TargetCountMap, + uint64_t &FunctionHash) { for (Depth = 0; Input[Depth] == ' '; Depth++) ; if (Depth == 0) return false; - if (Depth == 1 && Input[Depth] == '!') { - LineTy = LineType::Metadata; - return parseMetadata(Input.substr(Depth), FunctionHash); - } - + if (Depth == 1 && Input[Depth] == '!') { + LineTy = LineType::Metadata; + return parseMetadata(Input.substr(Depth), FunctionHash); + } + size_t n1 = Input.find(':'); StringRef Loc = Input.substr(Depth, n1 - Depth); size_t n2 = Loc.find('.'); @@ -144,8 +144,8 @@ static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth, } StringRef Rest = Input.substr(n1 + 2); - if (isDigit(Rest[0])) { - LineTy = LineType::BodyProfile; + if (isDigit(Rest[0])) { + LineTy = LineType::BodyProfile; size_t n3 = Rest.find(' '); if (n3 == StringRef::npos) { if (Rest.getAsInteger(10, NumSamples)) @@ -202,7 +202,7 @@ static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth, n3 = n4; } } else { - LineTy = LineType::CallSiteProfile; + LineTy = LineType::CallSiteProfile; size_t n3 = Rest.find_last_of(':'); CalleeName = Rest.substr(0, n3); if (Rest.substr(n3 + 1).getAsInteger(10, NumSamples)) @@ -222,12 +222,12 @@ std::error_code SampleProfileReaderText::readImpl() { sampleprof_error Result = sampleprof_error::success; InlineCallStack InlineStack; - uint32_t ProbeProfileCount = 0; + uint32_t ProbeProfileCount = 0; + + // SeenMetadata tracks whether we have processed metadata for the current + // top-level function profile. + bool SeenMetadata = false; - // SeenMetadata tracks whether we have processed metadata for the current - // top-level function profile. - bool SeenMetadata = false; - for (; !LineIt.is_at_eof(); ++LineIt) { if ((*LineIt)[(*LineIt).find_first_not_of(' ')] == '#') continue; @@ -251,14 +251,14 @@ std::error_code SampleProfileReaderText::readImpl() { "Expected 'mangled_name:NUM:NUM', found " + *LineIt); return sampleprof_error::malformed; } - SeenMetadata = false; - SampleContext FContext(FName); - if (FContext.hasContext()) - ++CSProfileCount; - Profiles[FContext] = FunctionSamples(); - FunctionSamples &FProfile = Profiles[FContext]; - FProfile.setName(FContext.getNameWithoutContext()); - FProfile.setContext(FContext); + SeenMetadata = false; + SampleContext FContext(FName); + if (FContext.hasContext()) + ++CSProfileCount; + Profiles[FContext] = FunctionSamples(); + FunctionSamples &FProfile = Profiles[FContext]; + FProfile.setName(FContext.getNameWithoutContext()); + FProfile.setContext(FContext); MergeResult(Result, FProfile.addTotalSamples(NumSamples)); MergeResult(Result, FProfile.addHeadSamples(NumHeadSamples)); InlineStack.clear(); @@ -268,34 +268,34 @@ std::error_code SampleProfileReaderText::readImpl() { StringRef FName; DenseMap<StringRef, uint64_t> TargetCountMap; uint32_t Depth, LineOffset, Discriminator; - LineType LineTy; - uint64_t FunctionHash; - if (!ParseLine(*LineIt, LineTy, Depth, NumSamples, LineOffset, - Discriminator, FName, TargetCountMap, FunctionHash)) { + LineType LineTy; + uint64_t FunctionHash; + if (!ParseLine(*LineIt, LineTy, Depth, NumSamples, LineOffset, + Discriminator, FName, TargetCountMap, FunctionHash)) { reportError(LineIt.line_number(), "Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found " + *LineIt); return sampleprof_error::malformed; } - if (SeenMetadata && LineTy != LineType::Metadata) { - // Metadata must be put at the end of a function profile. - reportError(LineIt.line_number(), - "Found non-metadata after metadata: " + *LineIt); - return sampleprof_error::malformed; - } - while (InlineStack.size() > Depth) { - InlineStack.pop_back(); - } - switch (LineTy) { - case LineType::CallSiteProfile: { + if (SeenMetadata && LineTy != LineType::Metadata) { + // Metadata must be put at the end of a function profile. + reportError(LineIt.line_number(), + "Found non-metadata after metadata: " + *LineIt); + return sampleprof_error::malformed; + } + while (InlineStack.size() > Depth) { + InlineStack.pop_back(); + } + switch (LineTy) { + case LineType::CallSiteProfile: { FunctionSamples &FSamples = InlineStack.back()->functionSamplesAt( LineLocation(LineOffset, Discriminator))[std::string(FName)]; FSamples.setName(FName); MergeResult(Result, FSamples.addTotalSamples(NumSamples)); InlineStack.push_back(&FSamples); - break; - } - case LineType::BodyProfile: { + break; + } + case LineType::BodyProfile: { while (InlineStack.size() > Depth) { InlineStack.pop_back(); } @@ -307,28 +307,28 @@ std::error_code SampleProfileReaderText::readImpl() { } MergeResult(Result, FProfile.addBodySamples(LineOffset, Discriminator, NumSamples)); - break; + break; + } + case LineType::Metadata: { + FunctionSamples &FProfile = *InlineStack.back(); + FProfile.setFunctionHash(FunctionHash); + ++ProbeProfileCount; + SeenMetadata = true; + break; + } } - case LineType::Metadata: { - FunctionSamples &FProfile = *InlineStack.back(); - FProfile.setFunctionHash(FunctionHash); - ++ProbeProfileCount; - SeenMetadata = true; - break; - } - } } } - - assert((CSProfileCount == 0 || CSProfileCount == Profiles.size()) && - "Cannot have both context-sensitive and regular profile"); - ProfileIsCS = (CSProfileCount > 0); - assert((ProbeProfileCount == 0 || ProbeProfileCount == Profiles.size()) && - "Cannot have both probe-based profiles and regular profiles"); - ProfileIsProbeBased = (ProbeProfileCount > 0); - FunctionSamples::ProfileIsProbeBased = ProfileIsProbeBased; - FunctionSamples::ProfileIsCS = ProfileIsCS; - + + assert((CSProfileCount == 0 || CSProfileCount == Profiles.size()) && + "Cannot have both context-sensitive and regular profile"); + ProfileIsCS = (CSProfileCount > 0); + assert((ProbeProfileCount == 0 || ProbeProfileCount == Profiles.size()) && + "Cannot have both probe-based profiles and regular profiles"); + ProfileIsProbeBased = (ProbeProfileCount > 0); + FunctionSamples::ProfileIsProbeBased = ProfileIsProbeBased; + FunctionSamples::ProfileIsCS = ProfileIsCS; + if (Result == sampleprof_error::success) computeSummary(); @@ -419,34 +419,34 @@ ErrorOr<StringRef> SampleProfileReaderBinary::readStringFromTable() { return NameTable[*Idx]; } -ErrorOr<StringRef> SampleProfileReaderExtBinaryBase::readStringFromTable() { - if (!FixedLengthMD5) - return SampleProfileReaderBinary::readStringFromTable(); - - // read NameTable index. - auto Idx = readStringIndex(NameTable); - if (std::error_code EC = Idx.getError()) - return EC; - - // Check whether the name to be accessed has been accessed before, - // if not, read it from memory directly. - StringRef &SR = NameTable[*Idx]; - if (SR.empty()) { - const uint8_t *SavedData = Data; - Data = MD5NameMemStart + ((*Idx) * sizeof(uint64_t)); - auto FID = readUnencodedNumber<uint64_t>(); - if (std::error_code EC = FID.getError()) - return EC; - // Save the string converted from uint64_t in MD5StringBuf. All the - // references to the name are all StringRefs refering to the string - // in MD5StringBuf. - MD5StringBuf->push_back(std::to_string(*FID)); - SR = MD5StringBuf->back(); - Data = SavedData; - } - return SR; -} - +ErrorOr<StringRef> SampleProfileReaderExtBinaryBase::readStringFromTable() { + if (!FixedLengthMD5) + return SampleProfileReaderBinary::readStringFromTable(); + + // read NameTable index. + auto Idx = readStringIndex(NameTable); + if (std::error_code EC = Idx.getError()) + return EC; + + // Check whether the name to be accessed has been accessed before, + // if not, read it from memory directly. + StringRef &SR = NameTable[*Idx]; + if (SR.empty()) { + const uint8_t *SavedData = Data; + Data = MD5NameMemStart + ((*Idx) * sizeof(uint64_t)); + auto FID = readUnencodedNumber<uint64_t>(); + if (std::error_code EC = FID.getError()) + return EC; + // Save the string converted from uint64_t in MD5StringBuf. All the + // references to the name are all StringRefs refering to the string + // in MD5StringBuf. + MD5StringBuf->push_back(std::to_string(*FID)); + SR = MD5StringBuf->back(); + Data = SavedData; + } + return SR; +} + ErrorOr<StringRef> SampleProfileReaderCompactBinary::readStringFromTable() { auto Idx = readStringIndex(NameTable); if (std::error_code EC = Idx.getError()) @@ -543,16 +543,16 @@ SampleProfileReaderBinary::readFuncProfile(const uint8_t *Start) { if (std::error_code EC = FName.getError()) return EC; - SampleContext FContext(*FName); - Profiles[FContext] = FunctionSamples(); - FunctionSamples &FProfile = Profiles[FContext]; - FProfile.setName(FContext.getNameWithoutContext()); - FProfile.setContext(FContext); + SampleContext FContext(*FName); + Profiles[FContext] = FunctionSamples(); + FunctionSamples &FProfile = Profiles[FContext]; + FProfile.setName(FContext.getNameWithoutContext()); + FProfile.setContext(FContext); FProfile.addHeadSamples(*NumHeadSamples); - if (FContext.hasContext()) - CSProfileCount++; - + if (FContext.hasContext()) + CSProfileCount++; + if (std::error_code EC = readProfile(FProfile)) return EC; return sampleprof_error::success; @@ -567,7 +567,7 @@ std::error_code SampleProfileReaderBinary::readImpl() { return sampleprof_error::success; } -std::error_code SampleProfileReaderExtBinaryBase::readOneSection( +std::error_code SampleProfileReaderExtBinaryBase::readOneSection( const uint8_t *Start, uint64_t Size, const SecHdrTableEntry &Entry) { Data = Start; End = Start + Size; @@ -578,56 +578,56 @@ std::error_code SampleProfileReaderExtBinaryBase::readOneSection( if (hasSecFlag(Entry, SecProfSummaryFlags::SecFlagPartial)) Summary->setPartialProfile(true); break; - case SecNameTable: { - FixedLengthMD5 = - hasSecFlag(Entry, SecNameTableFlags::SecFlagFixedLengthMD5); - bool UseMD5 = hasSecFlag(Entry, SecNameTableFlags::SecFlagMD5Name); - assert((!FixedLengthMD5 || UseMD5) && - "If FixedLengthMD5 is true, UseMD5 has to be true"); - if (std::error_code EC = readNameTableSec(UseMD5)) + case SecNameTable: { + FixedLengthMD5 = + hasSecFlag(Entry, SecNameTableFlags::SecFlagFixedLengthMD5); + bool UseMD5 = hasSecFlag(Entry, SecNameTableFlags::SecFlagMD5Name); + assert((!FixedLengthMD5 || UseMD5) && + "If FixedLengthMD5 is true, UseMD5 has to be true"); + if (std::error_code EC = readNameTableSec(UseMD5)) return EC; break; - } + } case SecLBRProfile: if (std::error_code EC = readFuncProfiles()) return EC; break; - case SecFuncOffsetTable: - if (std::error_code EC = readFuncOffsetTable()) - return EC; - break; - case SecFuncMetadata: - ProfileIsProbeBased = - hasSecFlag(Entry, SecFuncMetadataFlags::SecFlagIsProbeBased); - FunctionSamples::ProfileIsProbeBased = ProfileIsProbeBased; - if (std::error_code EC = readFuncMetadata()) - return EC; - break; + case SecFuncOffsetTable: + if (std::error_code EC = readFuncOffsetTable()) + return EC; + break; + case SecFuncMetadata: + ProfileIsProbeBased = + hasSecFlag(Entry, SecFuncMetadataFlags::SecFlagIsProbeBased); + FunctionSamples::ProfileIsProbeBased = ProfileIsProbeBased; + if (std::error_code EC = readFuncMetadata()) + return EC; + break; case SecProfileSymbolList: if (std::error_code EC = readProfileSymbolList()) return EC; break; - default: - if (std::error_code EC = readCustomSection(Entry)) + default: + if (std::error_code EC = readCustomSection(Entry)) return EC; break; } return sampleprof_error::success; } -void SampleProfileReaderExtBinaryBase::collectFuncsFrom(const Module &M) { +void SampleProfileReaderExtBinaryBase::collectFuncsFrom(const Module &M) { UseAllFuncs = false; FuncsToUse.clear(); for (auto &F : M) FuncsToUse.insert(FunctionSamples::getCanonicalFnName(F)); } -std::error_code SampleProfileReaderExtBinaryBase::readFuncOffsetTable() { - // If there are more than one FuncOffsetTable, the profile read associated - // with previous FuncOffsetTable has to be done before next FuncOffsetTable - // is read. - FuncOffsetTable.clear(); - +std::error_code SampleProfileReaderExtBinaryBase::readFuncOffsetTable() { + // If there are more than one FuncOffsetTable, the profile read associated + // with previous FuncOffsetTable has to be done before next FuncOffsetTable + // is read. + FuncOffsetTable.clear(); + auto Size = readNumber<uint64_t>(); if (std::error_code EC = Size.getError()) return EC; @@ -647,7 +647,7 @@ std::error_code SampleProfileReaderExtBinaryBase::readFuncOffsetTable() { return sampleprof_error::success; } -std::error_code SampleProfileReaderExtBinaryBase::readFuncProfiles() { +std::error_code SampleProfileReaderExtBinaryBase::readFuncProfiles() { const uint8_t *Start = Data; if (UseAllFuncs) { while (Data < End) { @@ -655,48 +655,48 @@ std::error_code SampleProfileReaderExtBinaryBase::readFuncProfiles() { return EC; } assert(Data == End && "More data is read than expected"); - } else { - if (Remapper) { - for (auto Name : FuncsToUse) { - Remapper->insert(Name); - } + } else { + if (Remapper) { + for (auto Name : FuncsToUse) { + Remapper->insert(Name); + } } - if (useMD5()) { - for (auto Name : FuncsToUse) { - auto GUID = std::to_string(MD5Hash(Name)); - auto iter = FuncOffsetTable.find(StringRef(GUID)); - if (iter == FuncOffsetTable.end()) - continue; - const uint8_t *FuncProfileAddr = Start + iter->second; - assert(FuncProfileAddr < End && "out of LBRProfile section"); - if (std::error_code EC = readFuncProfile(FuncProfileAddr)) - return EC; - } - } else { - for (auto NameOffset : FuncOffsetTable) { - SampleContext FContext(NameOffset.first); - auto FuncName = FContext.getNameWithoutContext(); - if (!FuncsToUse.count(FuncName) && - (!Remapper || !Remapper->exist(FuncName))) - continue; - const uint8_t *FuncProfileAddr = Start + NameOffset.second; - assert(FuncProfileAddr < End && "out of LBRProfile section"); - if (std::error_code EC = readFuncProfile(FuncProfileAddr)) - return EC; - } + if (useMD5()) { + for (auto Name : FuncsToUse) { + auto GUID = std::to_string(MD5Hash(Name)); + auto iter = FuncOffsetTable.find(StringRef(GUID)); + if (iter == FuncOffsetTable.end()) + continue; + const uint8_t *FuncProfileAddr = Start + iter->second; + assert(FuncProfileAddr < End && "out of LBRProfile section"); + if (std::error_code EC = readFuncProfile(FuncProfileAddr)) + return EC; + } + } else { + for (auto NameOffset : FuncOffsetTable) { + SampleContext FContext(NameOffset.first); + auto FuncName = FContext.getNameWithoutContext(); + if (!FuncsToUse.count(FuncName) && + (!Remapper || !Remapper->exist(FuncName))) + continue; + const uint8_t *FuncProfileAddr = Start + NameOffset.second; + assert(FuncProfileAddr < End && "out of LBRProfile section"); + if (std::error_code EC = readFuncProfile(FuncProfileAddr)) + return EC; + } } - Data = End; + Data = End; } - assert((CSProfileCount == 0 || CSProfileCount == Profiles.size()) && - "Cannot have both context-sensitive and regular profile"); - ProfileIsCS = (CSProfileCount > 0); - FunctionSamples::ProfileIsCS = ProfileIsCS; + assert((CSProfileCount == 0 || CSProfileCount == Profiles.size()) && + "Cannot have both context-sensitive and regular profile"); + ProfileIsCS = (CSProfileCount > 0); + FunctionSamples::ProfileIsCS = ProfileIsCS; return sampleprof_error::success; } -std::error_code SampleProfileReaderExtBinaryBase::readProfileSymbolList() { +std::error_code SampleProfileReaderExtBinaryBase::readProfileSymbolList() { if (!ProfSymList) ProfSymList = std::make_unique<ProfileSymbolList>(); @@ -745,10 +745,10 @@ std::error_code SampleProfileReaderExtBinaryBase::readImpl() { if (!Entry.Size) continue; - // Skip sections without context when SkipFlatProf is true. - if (SkipFlatProf && hasSecFlag(Entry, SecCommonFlags::SecFlagFlat)) - continue; - + // Skip sections without context when SkipFlatProf is true. + if (SkipFlatProf && hasSecFlag(Entry, SecCommonFlags::SecFlagFlat)) + continue; + const uint8_t *SecStart = BufStart + Entry.Offset; uint64_t SecSize = Entry.Size; @@ -833,7 +833,7 @@ std::error_code SampleProfileReaderBinary::readNameTable() { auto Size = readNumber<uint32_t>(); if (std::error_code EC = Size.getError()) return EC; - NameTable.reserve(*Size + NameTable.size()); + NameTable.reserve(*Size + NameTable.size()); for (uint32_t I = 0; I < *Size; ++I) { auto Name(readString()); if (std::error_code EC = Name.getError()) @@ -844,24 +844,24 @@ std::error_code SampleProfileReaderBinary::readNameTable() { return sampleprof_error::success; } -std::error_code SampleProfileReaderExtBinaryBase::readMD5NameTable() { +std::error_code SampleProfileReaderExtBinaryBase::readMD5NameTable() { auto Size = readNumber<uint64_t>(); if (std::error_code EC = Size.getError()) return EC; MD5StringBuf = std::make_unique<std::vector<std::string>>(); MD5StringBuf->reserve(*Size); - if (FixedLengthMD5) { - // Preallocate and initialize NameTable so we can check whether a name - // index has been read before by checking whether the element in the - // NameTable is empty, meanwhile readStringIndex can do the boundary - // check using the size of NameTable. - NameTable.resize(*Size + NameTable.size()); - - MD5NameMemStart = Data; - Data = Data + (*Size) * sizeof(uint64_t); - return sampleprof_error::success; - } - NameTable.reserve(*Size); + if (FixedLengthMD5) { + // Preallocate and initialize NameTable so we can check whether a name + // index has been read before by checking whether the element in the + // NameTable is empty, meanwhile readStringIndex can do the boundary + // check using the size of NameTable. + NameTable.resize(*Size + NameTable.size()); + + MD5NameMemStart = Data; + Data = Data + (*Size) * sizeof(uint64_t); + return sampleprof_error::success; + } + NameTable.reserve(*Size); for (uint32_t I = 0; I < *Size; ++I) { auto FID = readNumber<uint64_t>(); if (std::error_code EC = FID.getError()) @@ -874,35 +874,35 @@ std::error_code SampleProfileReaderExtBinaryBase::readMD5NameTable() { return sampleprof_error::success; } -std::error_code SampleProfileReaderExtBinaryBase::readNameTableSec(bool IsMD5) { +std::error_code SampleProfileReaderExtBinaryBase::readNameTableSec(bool IsMD5) { if (IsMD5) return readMD5NameTable(); return SampleProfileReaderBinary::readNameTable(); } -std::error_code SampleProfileReaderExtBinaryBase::readFuncMetadata() { - if (!ProfileIsProbeBased) - return sampleprof_error::success; - while (Data < End) { - auto FName(readStringFromTable()); - if (std::error_code EC = FName.getError()) - return EC; - - auto Checksum = readNumber<uint64_t>(); - if (std::error_code EC = Checksum.getError()) - return EC; - - SampleContext FContext(*FName); - // No need to load metadata for profiles that are not loaded in the current - // module. - if (Profiles.count(FContext)) - Profiles[FContext].setFunctionHash(*Checksum); - } - - assert(Data == End && "More data is read than expected"); - return sampleprof_error::success; -} - +std::error_code SampleProfileReaderExtBinaryBase::readFuncMetadata() { + if (!ProfileIsProbeBased) + return sampleprof_error::success; + while (Data < End) { + auto FName(readStringFromTable()); + if (std::error_code EC = FName.getError()) + return EC; + + auto Checksum = readNumber<uint64_t>(); + if (std::error_code EC = Checksum.getError()) + return EC; + + SampleContext FContext(*FName); + // No need to load metadata for profiles that are not loaded in the current + // module. + if (Profiles.count(FContext)) + Profiles[FContext].setFunctionHash(*Checksum); + } + + assert(Data == End && "More data is read than expected"); + return sampleprof_error::success; +} + std::error_code SampleProfileReaderCompactBinary::readNameTable() { auto Size = readNumber<uint64_t>(); if (std::error_code EC = Size.getError()) @@ -917,8 +917,8 @@ std::error_code SampleProfileReaderCompactBinary::readNameTable() { return sampleprof_error::success; } -std::error_code -SampleProfileReaderExtBinaryBase::readSecHdrTableEntry(uint32_t Idx) { +std::error_code +SampleProfileReaderExtBinaryBase::readSecHdrTableEntry(uint32_t Idx) { SecHdrTableEntry Entry; auto Type = readUnencodedNumber<uint64_t>(); if (std::error_code EC = Type.getError()) @@ -940,7 +940,7 @@ SampleProfileReaderExtBinaryBase::readSecHdrTableEntry(uint32_t Idx) { return EC; Entry.Size = *Size; - Entry.LayoutIndex = Idx; + Entry.LayoutIndex = Idx; SecHdrTable.push_back(std::move(Entry)); return sampleprof_error::success; } @@ -951,7 +951,7 @@ std::error_code SampleProfileReaderExtBinaryBase::readSecHdrTable() { return EC; for (uint32_t i = 0; i < (*EntryNum); i++) - if (std::error_code EC = readSecHdrTableEntry(i)) + if (std::error_code EC = readSecHdrTableEntry(i)) return EC; return sampleprof_error::success; @@ -973,12 +973,12 @@ std::error_code SampleProfileReaderExtBinaryBase::readHeader() { } uint64_t SampleProfileReaderExtBinaryBase::getSectionSize(SecType Type) { - uint64_t Size = 0; + uint64_t Size = 0; for (auto &Entry : SecHdrTable) { if (Entry.Type == Type) - Size += Entry.Size; + Size += Entry.Size; } - return Size; + return Size; } uint64_t SampleProfileReaderExtBinaryBase::getFileSize() { @@ -1001,14 +1001,14 @@ static std::string getSecFlagsStr(const SecHdrTableEntry &Entry) { else Flags.append("{"); - if (hasSecFlag(Entry, SecCommonFlags::SecFlagFlat)) - Flags.append("flat,"); - + if (hasSecFlag(Entry, SecCommonFlags::SecFlagFlat)) + Flags.append("flat,"); + switch (Entry.Type) { case SecNameTable: - if (hasSecFlag(Entry, SecNameTableFlags::SecFlagFixedLengthMD5)) - Flags.append("fixlenmd5,"); - else if (hasSecFlag(Entry, SecNameTableFlags::SecFlagMD5Name)) + if (hasSecFlag(Entry, SecNameTableFlags::SecFlagFixedLengthMD5)) + Flags.append("fixlenmd5,"); + else if (hasSecFlag(Entry, SecNameTableFlags::SecFlagMD5Name)) Flags.append("md5,"); break; case SecProfSummary: @@ -1033,7 +1033,7 @@ bool SampleProfileReaderExtBinaryBase::dumpSectionInfo(raw_ostream &OS) { << ", Size: " << Entry.Size << ", Flags: " << getSecFlagsStr(Entry) << "\n"; ; - TotalSecsSize += Entry.Size; + TotalSecsSize += Entry.Size; } uint64_t HeaderSize = SecHdrTable.front().Offset; assert(HeaderSize + TotalSecsSize == getFileSize() && @@ -1367,7 +1367,7 @@ std::error_code SampleProfileReaderGCC::readOneFunctionProfile( InlineCallStack NewStack; NewStack.push_back(FProfile); - llvm::append_range(NewStack, InlineStack); + llvm::append_range(NewStack, InlineStack); if (Update) { // Walk up the inline stack, adding the samples on this line to // the total sample count of the callers in the chain. @@ -1415,7 +1415,7 @@ std::error_code SampleProfileReaderGCC::readOneFunctionProfile( return sampleprof_error::truncated; InlineCallStack NewStack; NewStack.push_back(FProfile); - llvm::append_range(NewStack, InlineStack); + llvm::append_range(NewStack, InlineStack); if (std::error_code EC = readOneFunctionProfile(NewStack, Update, Offset)) return EC; } @@ -1456,25 +1456,25 @@ void SampleProfileReaderItaniumRemapper::applyRemapping(LLVMContext &Ctx) { return; } - // CSSPGO-TODO: Remapper is not yet supported. - // We will need to remap the entire context string. + // CSSPGO-TODO: Remapper is not yet supported. + // We will need to remap the entire context string. assert(Remappings && "should be initialized while creating remapper"); - for (auto &Sample : Reader.getProfiles()) { - DenseSet<StringRef> NamesInSample; - Sample.second.findAllNames(NamesInSample); - for (auto &Name : NamesInSample) - if (auto Key = Remappings->insert(Name)) - NameMap.insert({Key, Name}); - } + for (auto &Sample : Reader.getProfiles()) { + DenseSet<StringRef> NamesInSample; + Sample.second.findAllNames(NamesInSample); + for (auto &Name : NamesInSample) + if (auto Key = Remappings->insert(Name)) + NameMap.insert({Key, Name}); + } RemappingApplied = true; } -Optional<StringRef> -SampleProfileReaderItaniumRemapper::lookUpNameInProfile(StringRef Fname) { +Optional<StringRef> +SampleProfileReaderItaniumRemapper::lookUpNameInProfile(StringRef Fname) { if (auto Key = Remappings->lookup(Fname)) - return NameMap.lookup(Key); - return None; + return NameMap.lookup(Key); + return None; } /// Prepare a memory buffer for the contents of \p Filename. @@ -1610,5 +1610,5 @@ SampleProfileReader::create(std::unique_ptr<MemoryBuffer> &B, LLVMContext &C, // profile. Binary format has the profile summary in its header. void SampleProfileReader::computeSummary() { SampleProfileSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs); - Summary = Builder.computeSummaryForProfiles(Profiles); + Summary = Builder.computeSummaryForProfiles(Profiles); } diff --git a/contrib/libs/llvm12/lib/ProfileData/SampleProfWriter.cpp b/contrib/libs/llvm12/lib/ProfileData/SampleProfWriter.cpp index 0122712a0c..8017f2a828 100644 --- a/contrib/libs/llvm12/lib/ProfileData/SampleProfWriter.cpp +++ b/contrib/libs/llvm12/lib/ProfileData/SampleProfWriter.cpp @@ -19,7 +19,7 @@ #include "llvm/ProfileData/SampleProfWriter.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/StringSet.h" +#include "llvm/ADT/StringSet.h" #include "llvm/ProfileData/ProfileCommon.h" #include "llvm/ProfileData/SampleProf.h" #include "llvm/Support/Compression.h" @@ -75,15 +75,15 @@ SampleProfileWriter::write(const StringMap<FunctionSamples> &ProfileMap) { } /// Return the current position and prepare to use it as the start -/// position of a section given the section type \p Type and its position -/// \p LayoutIdx in SectionHdrLayout. -uint64_t -SampleProfileWriterExtBinaryBase::markSectionStart(SecType Type, - uint32_t LayoutIdx) { +/// position of a section given the section type \p Type and its position +/// \p LayoutIdx in SectionHdrLayout. +uint64_t +SampleProfileWriterExtBinaryBase::markSectionStart(SecType Type, + uint32_t LayoutIdx) { uint64_t SectionStart = OutputStream->tell(); - assert(LayoutIdx < SectionHdrLayout.size() && "LayoutIdx out of range"); - const auto &Entry = SectionHdrLayout[LayoutIdx]; - assert(Entry.Type == Type && "Unexpected section type"); + assert(LayoutIdx < SectionHdrLayout.size() && "LayoutIdx out of range"); + const auto &Entry = SectionHdrLayout[LayoutIdx]; + assert(Entry.Type == Type && "Unexpected section type"); // Use LocalBuf as a temporary output for writting data. if (hasSecFlag(Entry, SecCommonFlags::SecFlagCompress)) LocalBufStream.swap(OutputStream); @@ -110,21 +110,21 @@ std::error_code SampleProfileWriterExtBinaryBase::compressAndOutput() { return sampleprof_error::success; } -/// Add a new section into section header table given the section type -/// \p Type, its position \p LayoutIdx in SectionHdrLayout and the -/// location \p SectionStart where the section should be written to. -std::error_code SampleProfileWriterExtBinaryBase::addNewSection( - SecType Type, uint32_t LayoutIdx, uint64_t SectionStart) { - assert(LayoutIdx < SectionHdrLayout.size() && "LayoutIdx out of range"); - const auto &Entry = SectionHdrLayout[LayoutIdx]; - assert(Entry.Type == Type && "Unexpected section type"); +/// Add a new section into section header table given the section type +/// \p Type, its position \p LayoutIdx in SectionHdrLayout and the +/// location \p SectionStart where the section should be written to. +std::error_code SampleProfileWriterExtBinaryBase::addNewSection( + SecType Type, uint32_t LayoutIdx, uint64_t SectionStart) { + assert(LayoutIdx < SectionHdrLayout.size() && "LayoutIdx out of range"); + const auto &Entry = SectionHdrLayout[LayoutIdx]; + assert(Entry.Type == Type && "Unexpected section type"); if (hasSecFlag(Entry, SecCommonFlags::SecFlagCompress)) { LocalBufStream.swap(OutputStream); if (std::error_code EC = compressAndOutput()) return EC; } SecHdrTable.push_back({Type, Entry.Flags, SectionStart - FileStart, - OutputStream->tell() - SectionStart, LayoutIdx}); + OutputStream->tell() - SectionStart, LayoutIdx}); return sampleprof_error::success; } @@ -145,15 +145,15 @@ std::error_code SampleProfileWriterExtBinaryBase::write( } std::error_code -SampleProfileWriterExtBinaryBase::writeSample(const FunctionSamples &S) { +SampleProfileWriterExtBinaryBase::writeSample(const FunctionSamples &S) { uint64_t Offset = OutputStream->tell(); - StringRef Name = S.getNameWithContext(true); + StringRef Name = S.getNameWithContext(true); FuncOffsetTable[Name] = Offset - SecLBRProfileStart; encodeULEB128(S.getHeadSamples(), *OutputStream); return writeBody(S); } -std::error_code SampleProfileWriterExtBinaryBase::writeFuncOffsetTable() { +std::error_code SampleProfileWriterExtBinaryBase::writeFuncOffsetTable() { auto &OS = *OutputStream; // Write out the table size. @@ -164,23 +164,23 @@ std::error_code SampleProfileWriterExtBinaryBase::writeFuncOffsetTable() { writeNameIdx(entry.first); encodeULEB128(entry.second, OS); } - FuncOffsetTable.clear(); + FuncOffsetTable.clear(); return sampleprof_error::success; } -std::error_code SampleProfileWriterExtBinaryBase::writeFuncMetadata( - const StringMap<FunctionSamples> &Profiles) { - if (!FunctionSamples::ProfileIsProbeBased) - return sampleprof_error::success; - auto &OS = *OutputStream; - for (const auto &Entry : Profiles) { - writeNameIdx(Entry.first()); - encodeULEB128(Entry.second.getFunctionHash(), OS); - } - return sampleprof_error::success; -} - -std::error_code SampleProfileWriterExtBinaryBase::writeNameTable() { +std::error_code SampleProfileWriterExtBinaryBase::writeFuncMetadata( + const StringMap<FunctionSamples> &Profiles) { + if (!FunctionSamples::ProfileIsProbeBased) + return sampleprof_error::success; + auto &OS = *OutputStream; + for (const auto &Entry : Profiles) { + writeNameIdx(Entry.first()); + encodeULEB128(Entry.second.getFunctionHash(), OS); + } + return sampleprof_error::success; +} + +std::error_code SampleProfileWriterExtBinaryBase::writeNameTable() { if (!UseMD5) return SampleProfileWriterBinary::writeNameTable(); @@ -188,159 +188,159 @@ std::error_code SampleProfileWriterExtBinaryBase::writeNameTable() { std::set<StringRef> V; stablizeNameTable(V); - // Write out the MD5 name table. We wrote unencoded MD5 so reader can - // retrieve the name using the name index without having to read the - // whole name table. + // Write out the MD5 name table. We wrote unencoded MD5 so reader can + // retrieve the name using the name index without having to read the + // whole name table. encodeULEB128(NameTable.size(), OS); - support::endian::Writer Writer(OS, support::little); - for (auto N : V) - Writer.write(MD5Hash(N)); + support::endian::Writer Writer(OS, support::little); + for (auto N : V) + Writer.write(MD5Hash(N)); return sampleprof_error::success; } -std::error_code SampleProfileWriterExtBinaryBase::writeNameTableSection( +std::error_code SampleProfileWriterExtBinaryBase::writeNameTableSection( const StringMap<FunctionSamples> &ProfileMap) { for (const auto &I : ProfileMap) { addName(I.first()); addNames(I.second); } - if (auto EC = writeNameTable()) + if (auto EC = writeNameTable()) return EC; - return sampleprof_error::success; -} - -std::error_code -SampleProfileWriterExtBinaryBase::writeProfileSymbolListSection() { - if (ProfSymList && ProfSymList->size() > 0) - if (std::error_code EC = ProfSymList->write(*OutputStream)) - return EC; - - return sampleprof_error::success; -} - -std::error_code SampleProfileWriterExtBinaryBase::writeOneSection( - SecType Type, uint32_t LayoutIdx, - const StringMap<FunctionSamples> &ProfileMap) { - // The setting of SecFlagCompress should happen before markSectionStart. - if (Type == SecProfileSymbolList && ProfSymList && ProfSymList->toCompress()) + return sampleprof_error::success; +} + +std::error_code +SampleProfileWriterExtBinaryBase::writeProfileSymbolListSection() { + if (ProfSymList && ProfSymList->size() > 0) + if (std::error_code EC = ProfSymList->write(*OutputStream)) + return EC; + + return sampleprof_error::success; +} + +std::error_code SampleProfileWriterExtBinaryBase::writeOneSection( + SecType Type, uint32_t LayoutIdx, + const StringMap<FunctionSamples> &ProfileMap) { + // The setting of SecFlagCompress should happen before markSectionStart. + if (Type == SecProfileSymbolList && ProfSymList && ProfSymList->toCompress()) setToCompressSection(SecProfileSymbolList); - if (Type == SecFuncMetadata && FunctionSamples::ProfileIsProbeBased) - addSectionFlag(SecFuncMetadata, SecFuncMetadataFlags::SecFlagIsProbeBased); - - uint64_t SectionStart = markSectionStart(Type, LayoutIdx); - switch (Type) { - case SecProfSummary: - computeSummary(ProfileMap); - if (auto EC = writeSummary()) + if (Type == SecFuncMetadata && FunctionSamples::ProfileIsProbeBased) + addSectionFlag(SecFuncMetadata, SecFuncMetadataFlags::SecFlagIsProbeBased); + + uint64_t SectionStart = markSectionStart(Type, LayoutIdx); + switch (Type) { + case SecProfSummary: + computeSummary(ProfileMap); + if (auto EC = writeSummary()) + return EC; + break; + case SecNameTable: + if (auto EC = writeNameTableSection(ProfileMap)) + return EC; + break; + case SecLBRProfile: + SecLBRProfileStart = OutputStream->tell(); + if (std::error_code EC = writeFuncProfiles(ProfileMap)) + return EC; + break; + case SecFuncOffsetTable: + if (auto EC = writeFuncOffsetTable()) + return EC; + break; + case SecFuncMetadata: + if (std::error_code EC = writeFuncMetadata(ProfileMap)) + return EC; + break; + case SecProfileSymbolList: + if (auto EC = writeProfileSymbolListSection()) + return EC; + break; + default: + if (auto EC = writeCustomSection(Type)) return EC; - break; - case SecNameTable: - if (auto EC = writeNameTableSection(ProfileMap)) - return EC; - break; - case SecLBRProfile: - SecLBRProfileStart = OutputStream->tell(); - if (std::error_code EC = writeFuncProfiles(ProfileMap)) - return EC; - break; - case SecFuncOffsetTable: - if (auto EC = writeFuncOffsetTable()) - return EC; - break; - case SecFuncMetadata: - if (std::error_code EC = writeFuncMetadata(ProfileMap)) - return EC; - break; - case SecProfileSymbolList: - if (auto EC = writeProfileSymbolListSection()) - return EC; - break; - default: - if (auto EC = writeCustomSection(Type)) - return EC; - break; - } - if (std::error_code EC = addNewSection(Type, LayoutIdx, SectionStart)) + break; + } + if (std::error_code EC = addNewSection(Type, LayoutIdx, SectionStart)) + return EC; + return sampleprof_error::success; +} + +std::error_code SampleProfileWriterExtBinary::writeDefaultLayout( + const StringMap<FunctionSamples> &ProfileMap) { + // The const indices passed to writeOneSection below are specifying the + // positions of the sections in SectionHdrLayout. Look at + // initSectionHdrLayout to find out where each section is located in + // SectionHdrLayout. + if (auto EC = writeOneSection(SecProfSummary, 0, ProfileMap)) + return EC; + if (auto EC = writeOneSection(SecNameTable, 1, ProfileMap)) return EC; - return sampleprof_error::success; -} - -std::error_code SampleProfileWriterExtBinary::writeDefaultLayout( - const StringMap<FunctionSamples> &ProfileMap) { - // The const indices passed to writeOneSection below are specifying the - // positions of the sections in SectionHdrLayout. Look at - // initSectionHdrLayout to find out where each section is located in - // SectionHdrLayout. - if (auto EC = writeOneSection(SecProfSummary, 0, ProfileMap)) + if (auto EC = writeOneSection(SecLBRProfile, 3, ProfileMap)) return EC; - if (auto EC = writeOneSection(SecNameTable, 1, ProfileMap)) + if (auto EC = writeOneSection(SecProfileSymbolList, 4, ProfileMap)) + return EC; + if (auto EC = writeOneSection(SecFuncOffsetTable, 2, ProfileMap)) + return EC; + if (auto EC = writeOneSection(SecFuncMetadata, 5, ProfileMap)) return EC; - if (auto EC = writeOneSection(SecLBRProfile, 3, ProfileMap)) - return EC; - if (auto EC = writeOneSection(SecProfileSymbolList, 4, ProfileMap)) - return EC; - if (auto EC = writeOneSection(SecFuncOffsetTable, 2, ProfileMap)) - return EC; - if (auto EC = writeOneSection(SecFuncMetadata, 5, ProfileMap)) - return EC; - return sampleprof_error::success; -} - -static void -splitProfileMapToTwo(const StringMap<FunctionSamples> &ProfileMap, - StringMap<FunctionSamples> &ContextProfileMap, - StringMap<FunctionSamples> &NoContextProfileMap) { - for (const auto &I : ProfileMap) { - if (I.second.getCallsiteSamples().size()) - ContextProfileMap.insert({I.first(), I.second}); - else - NoContextProfileMap.insert({I.first(), I.second}); - } -} - -std::error_code SampleProfileWriterExtBinary::writeCtxSplitLayout( - const StringMap<FunctionSamples> &ProfileMap) { - StringMap<FunctionSamples> ContextProfileMap, NoContextProfileMap; - splitProfileMapToTwo(ProfileMap, ContextProfileMap, NoContextProfileMap); - - if (auto EC = writeOneSection(SecProfSummary, 0, ProfileMap)) - return EC; - if (auto EC = writeOneSection(SecNameTable, 1, ProfileMap)) - return EC; - if (auto EC = writeOneSection(SecLBRProfile, 3, ContextProfileMap)) - return EC; - if (auto EC = writeOneSection(SecFuncOffsetTable, 2, ContextProfileMap)) - return EC; - // Mark the section to have no context. Note section flag needs to be set - // before writing the section. - addSectionFlag(5, SecCommonFlags::SecFlagFlat); - if (auto EC = writeOneSection(SecLBRProfile, 5, NoContextProfileMap)) - return EC; - // Mark the section to have no context. Note section flag needs to be set - // before writing the section. - addSectionFlag(4, SecCommonFlags::SecFlagFlat); - if (auto EC = writeOneSection(SecFuncOffsetTable, 4, NoContextProfileMap)) - return EC; - if (auto EC = writeOneSection(SecProfileSymbolList, 6, ProfileMap)) - return EC; - if (auto EC = writeOneSection(SecFuncMetadata, 7, ProfileMap)) - return EC; - return sampleprof_error::success; } -std::error_code SampleProfileWriterExtBinary::writeSections( - const StringMap<FunctionSamples> &ProfileMap) { - std::error_code EC; - if (SecLayout == DefaultLayout) - EC = writeDefaultLayout(ProfileMap); - else if (SecLayout == CtxSplitLayout) - EC = writeCtxSplitLayout(ProfileMap); - else - llvm_unreachable("Unsupported layout"); - return EC; -} - +static void +splitProfileMapToTwo(const StringMap<FunctionSamples> &ProfileMap, + StringMap<FunctionSamples> &ContextProfileMap, + StringMap<FunctionSamples> &NoContextProfileMap) { + for (const auto &I : ProfileMap) { + if (I.second.getCallsiteSamples().size()) + ContextProfileMap.insert({I.first(), I.second}); + else + NoContextProfileMap.insert({I.first(), I.second}); + } +} + +std::error_code SampleProfileWriterExtBinary::writeCtxSplitLayout( + const StringMap<FunctionSamples> &ProfileMap) { + StringMap<FunctionSamples> ContextProfileMap, NoContextProfileMap; + splitProfileMapToTwo(ProfileMap, ContextProfileMap, NoContextProfileMap); + + if (auto EC = writeOneSection(SecProfSummary, 0, ProfileMap)) + return EC; + if (auto EC = writeOneSection(SecNameTable, 1, ProfileMap)) + return EC; + if (auto EC = writeOneSection(SecLBRProfile, 3, ContextProfileMap)) + return EC; + if (auto EC = writeOneSection(SecFuncOffsetTable, 2, ContextProfileMap)) + return EC; + // Mark the section to have no context. Note section flag needs to be set + // before writing the section. + addSectionFlag(5, SecCommonFlags::SecFlagFlat); + if (auto EC = writeOneSection(SecLBRProfile, 5, NoContextProfileMap)) + return EC; + // Mark the section to have no context. Note section flag needs to be set + // before writing the section. + addSectionFlag(4, SecCommonFlags::SecFlagFlat); + if (auto EC = writeOneSection(SecFuncOffsetTable, 4, NoContextProfileMap)) + return EC; + if (auto EC = writeOneSection(SecProfileSymbolList, 6, ProfileMap)) + return EC; + if (auto EC = writeOneSection(SecFuncMetadata, 7, ProfileMap)) + return EC; + + return sampleprof_error::success; +} + +std::error_code SampleProfileWriterExtBinary::writeSections( + const StringMap<FunctionSamples> &ProfileMap) { + std::error_code EC; + if (SecLayout == DefaultLayout) + EC = writeDefaultLayout(ProfileMap); + else if (SecLayout == CtxSplitLayout) + EC = writeCtxSplitLayout(ProfileMap); + else + llvm_unreachable("Unsupported layout"); + return EC; +} + std::error_code SampleProfileWriterCompactBinary::write( const StringMap<FunctionSamples> &ProfileMap) { if (std::error_code EC = SampleProfileWriter::write(ProfileMap)) @@ -360,7 +360,7 @@ std::error_code SampleProfileWriterCompactBinary::write( /// it needs to be parsed by the SampleProfileReaderText class. std::error_code SampleProfileWriterText::writeSample(const FunctionSamples &S) { auto &OS = *OutputStream; - OS << S.getNameWithContext(true) << ":" << S.getTotalSamples(); + OS << S.getNameWithContext(true) << ":" << S.getTotalSamples(); if (Indent == 0) OS << ":" << S.getHeadSamples(); OS << "\n"; @@ -399,13 +399,13 @@ std::error_code SampleProfileWriterText::writeSample(const FunctionSamples &S) { } Indent -= 1; - if (Indent == 0) { - if (FunctionSamples::ProfileIsProbeBased) { - OS.indent(Indent + 1); - OS << "!CFGChecksum: " << S.getFunctionHash() << "\n"; - } - } - + if (Indent == 0) { + if (FunctionSamples::ProfileIsProbeBased) { + OS.indent(Indent + 1); + OS << "!CFGChecksum: " << S.getFunctionHash() << "\n"; + } + } + return sampleprof_error::success; } @@ -556,31 +556,31 @@ std::error_code SampleProfileWriterExtBinaryBase::writeSecHdrTable() { return sampleprof_error::ostream_seek_unsupported; support::endian::Writer Writer(*OutputStream, support::little); - assert(SecHdrTable.size() == SectionHdrLayout.size() && - "SecHdrTable entries doesn't match SectionHdrLayout"); - SmallVector<uint32_t, 16> IndexMap(SecHdrTable.size(), -1); - for (uint32_t TableIdx = 0; TableIdx < SecHdrTable.size(); TableIdx++) { - IndexMap[SecHdrTable[TableIdx].LayoutIndex] = TableIdx; + assert(SecHdrTable.size() == SectionHdrLayout.size() && + "SecHdrTable entries doesn't match SectionHdrLayout"); + SmallVector<uint32_t, 16> IndexMap(SecHdrTable.size(), -1); + for (uint32_t TableIdx = 0; TableIdx < SecHdrTable.size(); TableIdx++) { + IndexMap[SecHdrTable[TableIdx].LayoutIndex] = TableIdx; } // Write the section header table in the order specified in - // SectionHdrLayout. SectionHdrLayout specifies the sections - // order in which profile reader expect to read, so the section - // header table should be written in the order in SectionHdrLayout. - // Note that the section order in SecHdrTable may be different - // from the order in SectionHdrLayout, for example, SecFuncOffsetTable - // needs to be computed after SecLBRProfile (the order in SecHdrTable), - // but it needs to be read before SecLBRProfile (the order in - // SectionHdrLayout). So we use IndexMap above to switch the order. - for (uint32_t LayoutIdx = 0; LayoutIdx < SectionHdrLayout.size(); - LayoutIdx++) { - assert(IndexMap[LayoutIdx] < SecHdrTable.size() && - "Incorrect LayoutIdx in SecHdrTable"); - auto Entry = SecHdrTable[IndexMap[LayoutIdx]]; - Writer.write(static_cast<uint64_t>(Entry.Type)); - Writer.write(static_cast<uint64_t>(Entry.Flags)); - Writer.write(static_cast<uint64_t>(Entry.Offset)); - Writer.write(static_cast<uint64_t>(Entry.Size)); + // SectionHdrLayout. SectionHdrLayout specifies the sections + // order in which profile reader expect to read, so the section + // header table should be written in the order in SectionHdrLayout. + // Note that the section order in SecHdrTable may be different + // from the order in SectionHdrLayout, for example, SecFuncOffsetTable + // needs to be computed after SecLBRProfile (the order in SecHdrTable), + // but it needs to be read before SecLBRProfile (the order in + // SectionHdrLayout). So we use IndexMap above to switch the order. + for (uint32_t LayoutIdx = 0; LayoutIdx < SectionHdrLayout.size(); + LayoutIdx++) { + assert(IndexMap[LayoutIdx] < SecHdrTable.size() && + "Incorrect LayoutIdx in SecHdrTable"); + auto Entry = SecHdrTable[IndexMap[LayoutIdx]]; + Writer.write(static_cast<uint64_t>(Entry.Type)); + Writer.write(static_cast<uint64_t>(Entry.Flags)); + Writer.write(static_cast<uint64_t>(Entry.Offset)); + Writer.write(static_cast<uint64_t>(Entry.Size)); } // Reset OutputStream. @@ -632,7 +632,7 @@ std::error_code SampleProfileWriterBinary::writeSummary() { std::error_code SampleProfileWriterBinary::writeBody(const FunctionSamples &S) { auto &OS = *OutputStream; - if (std::error_code EC = writeNameIdx(S.getNameWithContext(true))) + if (std::error_code EC = writeNameIdx(S.getNameWithContext(true))) return EC; encodeULEB128(S.getTotalSamples(), OS); @@ -749,5 +749,5 @@ SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS, void SampleProfileWriter::computeSummary( const StringMap<FunctionSamples> &ProfileMap) { SampleProfileSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs); - Summary = Builder.computeSummaryForProfiles(ProfileMap); + Summary = Builder.computeSummaryForProfiles(ProfileMap); } diff --git a/contrib/libs/llvm12/lib/ProfileData/ya.make b/contrib/libs/llvm12/lib/ProfileData/ya.make index 24c01a162b..1c3b40612f 100644 --- a/contrib/libs/llvm12/lib/ProfileData/ya.make +++ b/contrib/libs/llvm12/lib/ProfileData/ya.make @@ -12,11 +12,11 @@ LICENSE(Apache-2.0 WITH LLVM-exception) LICENSE_TEXTS(.yandex_meta/licenses.list.txt) PEERDIR( - contrib/libs/llvm12 - contrib/libs/llvm12/include - contrib/libs/llvm12/lib/Demangle - contrib/libs/llvm12/lib/IR - contrib/libs/llvm12/lib/Support + contrib/libs/llvm12 + contrib/libs/llvm12/include + contrib/libs/llvm12/lib/Demangle + contrib/libs/llvm12/lib/IR + contrib/libs/llvm12/lib/Support ) ADDINCL( |