diff options
author | Stephen Hines <srhines@google.com> | 2015-03-23 12:10:34 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2015-03-23 12:10:34 -0700 |
commit | ebe69fe11e48d322045d5949c83283927a0d790b (patch) | |
tree | c92f1907a6b8006628a4b01615f38264d29834ea /lib/ProfileData | |
parent | b7d2e72b02a4cb8034f32f8247a2558d2434e121 (diff) | |
download | external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.zip external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.tar.gz external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.tar.bz2 |
Update aosp/master LLVM for rebase to r230699.
Change-Id: I2b5be30509658cb8266be782de0ab24f9099f9b9
Diffstat (limited to 'lib/ProfileData')
-rw-r--r-- | lib/ProfileData/CMakeLists.txt | 3 | ||||
-rw-r--r-- | lib/ProfileData/CoverageMapping.cpp | 110 | ||||
-rw-r--r-- | lib/ProfileData/CoverageMappingReader.cpp | 161 | ||||
-rw-r--r-- | lib/ProfileData/CoverageMappingWriter.cpp | 8 | ||||
-rw-r--r-- | lib/ProfileData/InstrProfIndexed.h | 1 | ||||
-rw-r--r-- | lib/ProfileData/InstrProfReader.cpp | 42 | ||||
-rw-r--r-- | lib/ProfileData/InstrProfWriter.cpp | 34 | ||||
-rw-r--r-- | lib/ProfileData/SampleProfWriter.cpp | 2 |
8 files changed, 192 insertions, 169 deletions
diff --git a/lib/ProfileData/CMakeLists.txt b/lib/ProfileData/CMakeLists.txt index b9d472d..282760f 100644 --- a/lib/ProfileData/CMakeLists.txt +++ b/lib/ProfileData/CMakeLists.txt @@ -8,4 +8,7 @@ add_llvm_library(LLVMProfileData SampleProf.cpp SampleProfReader.cpp SampleProfWriter.cpp + + ADDITIONAL_HEADER_DIRS + ${LLVM_MAIN_INCLUDE_DIR}/llvm/ProfileData ) diff --git a/lib/ProfileData/CoverageMapping.cpp b/lib/ProfileData/CoverageMapping.cpp index 0ccebc2..31213d7 100644 --- a/lib/ProfileData/CoverageMapping.cpp +++ b/lib/ProfileData/CoverageMapping.cpp @@ -13,10 +13,9 @@ //===----------------------------------------------------------------------===// #include "llvm/ProfileData/CoverageMapping.h" - #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" -#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SmallBitVector.h" #include "llvm/ProfileData/CoverageMappingReader.h" #include "llvm/ProfileData/InstrProfReader.h" #include "llvm/Support/Debug.h" @@ -179,31 +178,32 @@ void FunctionRecordIterator::skipOtherFiles() { } ErrorOr<std::unique_ptr<CoverageMapping>> -CoverageMapping::load(ObjectFileCoverageMappingReader &CoverageReader, +CoverageMapping::load(CoverageMappingReader &CoverageReader, IndexedInstrProfReader &ProfileReader) { auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping()); std::vector<uint64_t> Counts; for (const auto &Record : CoverageReader) { + CounterMappingContext Ctx(Record.Expressions); + Counts.clear(); if (std::error_code EC = ProfileReader.getFunctionCounts( Record.FunctionName, Record.FunctionHash, Counts)) { - if (EC != instrprof_error::hash_mismatch && - EC != instrprof_error::unknown_function) + if (EC == instrprof_error::hash_mismatch) { + Coverage->MismatchedFunctionCount++; + continue; + } else if (EC != instrprof_error::unknown_function) return EC; - Coverage->MismatchedFunctionCount++; - continue; - } + } else + Ctx.setCounts(Counts); - assert(Counts.size() != 0 && "Function's counts are empty"); - FunctionRecord Function(Record.FunctionName, Record.Filenames, - Counts.front()); - CounterMappingContext Ctx(Record.Expressions, Counts); + assert(!Record.MappingRegions.empty() && "Function has no regions"); + FunctionRecord Function(Record.FunctionName, Record.Filenames); for (const auto &Region : Record.MappingRegions) { ErrorOr<int64_t> ExecutionCount = Ctx.evaluate(Region.Count); if (!ExecutionCount) break; - Function.CountedRegions.push_back(CountedRegion(Region, *ExecutionCount)); + Function.pushRegion(Region, *ExecutionCount); } if (Function.CountedRegions.size() != Record.MappingRegions.size()) { Coverage->MismatchedFunctionCount++; @@ -219,15 +219,18 @@ CoverageMapping::load(ObjectFileCoverageMappingReader &CoverageReader, ErrorOr<std::unique_ptr<CoverageMapping>> CoverageMapping::load(StringRef ObjectFilename, StringRef ProfileFilename) { auto CounterMappingBuff = MemoryBuffer::getFileOrSTDIN(ObjectFilename); - if (auto EC = CounterMappingBuff.getError()) + if (std::error_code EC = CounterMappingBuff.getError()) return EC; - ObjectFileCoverageMappingReader CoverageReader(CounterMappingBuff.get()); - if (auto EC = CoverageReader.readHeader()) + auto CoverageReaderOrErr = + BinaryCoverageReader::create(CounterMappingBuff.get()); + if (std::error_code EC = CoverageReaderOrErr.getError()) return EC; - std::unique_ptr<IndexedInstrProfReader> ProfileReader; - if (auto EC = IndexedInstrProfReader::create(ProfileFilename, ProfileReader)) + auto CoverageReader = std::move(CoverageReaderOrErr.get()); + auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename); + if (auto EC = ProfileReaderOrErr.getError()) return EC; - return load(CoverageReader, *ProfileReader); + auto ProfileReader = std::move(ProfileReaderOrErr.get()); + return load(*CoverageReader, *ProfileReader); } namespace { @@ -305,20 +308,22 @@ class SegmentBuilder { public: /// Build a list of CoverageSegments from a sorted list of Regions. std::vector<CoverageSegment> buildSegments(ArrayRef<CountedRegion> Regions) { + const CountedRegion *PrevRegion = nullptr; for (const auto &Region : Regions) { // Pop any regions that end before this one starts. while (!ActiveRegions.empty() && ActiveRegions.back()->endLoc() <= Region.startLoc()) popRegion(); - if (Segments.size() && Segments.back().Line == Region.LineStart && - Segments.back().Col == Region.ColumnStart) { - if (Region.Kind != coverage::CounterMappingRegion::SkippedRegion) + if (PrevRegion && PrevRegion->startLoc() == Region.startLoc() && + PrevRegion->endLoc() == Region.endLoc()) { + if (Region.Kind == coverage::CounterMappingRegion::CodeRegion) Segments.back().addCount(Region.ExecutionCount); } else { // Add this region to the stack. ActiveRegions.push_back(&Region); startSegment(Region); } + PrevRegion = &Region; } // Pop any regions that are left in the stack. while (!ActiveRegions.empty()) @@ -331,50 +336,47 @@ public: std::vector<StringRef> CoverageMapping::getUniqueSourceFiles() const { std::vector<StringRef> Filenames; for (const auto &Function : getCoveredFunctions()) - for (const auto &Filename : Function.Filenames) - Filenames.push_back(Filename); + Filenames.insert(Filenames.end(), Function.Filenames.begin(), + Function.Filenames.end()); std::sort(Filenames.begin(), Filenames.end()); auto Last = std::unique(Filenames.begin(), Filenames.end()); Filenames.erase(Last, Filenames.end()); return Filenames; } -static Optional<unsigned> findMainViewFileID(StringRef SourceFile, - const FunctionRecord &Function) { - llvm::SmallVector<bool, 8> IsExpandedFile(Function.Filenames.size(), false); - llvm::SmallVector<bool, 8> FilenameEquivalence(Function.Filenames.size(), - false); +static SmallBitVector gatherFileIDs(StringRef SourceFile, + const FunctionRecord &Function) { + SmallBitVector FilenameEquivalence(Function.Filenames.size(), false); for (unsigned I = 0, E = Function.Filenames.size(); I < E; ++I) if (SourceFile == Function.Filenames[I]) FilenameEquivalence[I] = true; + return FilenameEquivalence; +} + +static Optional<unsigned> findMainViewFileID(StringRef SourceFile, + const FunctionRecord &Function) { + SmallBitVector IsNotExpandedFile(Function.Filenames.size(), true); + SmallBitVector FilenameEquivalence = gatherFileIDs(SourceFile, Function); for (const auto &CR : Function.CountedRegions) if (CR.Kind == CounterMappingRegion::ExpansionRegion && FilenameEquivalence[CR.FileID]) - IsExpandedFile[CR.ExpandedFileID] = true; - for (unsigned I = 0, E = Function.Filenames.size(); I < E; ++I) - if (FilenameEquivalence[I] && !IsExpandedFile[I]) - return I; - return None; + IsNotExpandedFile[CR.ExpandedFileID] = false; + IsNotExpandedFile &= FilenameEquivalence; + int I = IsNotExpandedFile.find_first(); + if (I == -1) + return None; + return I; } static Optional<unsigned> findMainViewFileID(const FunctionRecord &Function) { - llvm::SmallVector<bool, 8> IsExpandedFile(Function.Filenames.size(), false); + SmallBitVector IsNotExpandedFile(Function.Filenames.size(), true); for (const auto &CR : Function.CountedRegions) if (CR.Kind == CounterMappingRegion::ExpansionRegion) - IsExpandedFile[CR.ExpandedFileID] = true; - for (unsigned I = 0, E = Function.Filenames.size(); I < E; ++I) - if (!IsExpandedFile[I]) - return I; - return None; -} - -static SmallSet<unsigned, 8> gatherFileIDs(StringRef SourceFile, - const FunctionRecord &Function) { - SmallSet<unsigned, 8> IDs; - for (unsigned I = 0, E = Function.Filenames.size(); I < E; ++I) - if (SourceFile == Function.Filenames[I]) - IDs.insert(I); - return IDs; + IsNotExpandedFile[CR.ExpandedFileID] = false; + int I = IsNotExpandedFile.find_first(); + if (I == -1) + return None; + return I; } /// Sort a nested sequence of regions from a single file. @@ -402,7 +404,7 @@ CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) { continue; auto FileIDs = gatherFileIDs(Filename, Function); for (const auto &CR : Function.CountedRegions) - if (FileIDs.count(CR.FileID)) { + if (FileIDs.test(CR.FileID)) { Regions.push_back(CR); if (isExpansion(CR, *MainFileID)) FileCoverage.Expansions.emplace_back(CR, Function); @@ -410,6 +412,7 @@ CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) { } sortNestedRegions(Regions.begin(), Regions.end()); + DEBUG(dbgs() << "Emitting segments for file: " << Filename << "\n"); FileCoverage.Segments = SegmentBuilder().buildSegments(Regions); return FileCoverage; @@ -429,8 +432,8 @@ CoverageMapping::getInstantiations(StringRef Filename) { for (const auto &InstantiationSet : InstantiationSetCollector) { if (InstantiationSet.second.size() < 2) continue; - for (auto Function : InstantiationSet.second) - Result.push_back(Function); + Result.insert(Result.end(), InstantiationSet.second.begin(), + InstantiationSet.second.end()); } return Result; } @@ -451,6 +454,7 @@ CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) { } sortNestedRegions(Regions.begin(), Regions.end()); + DEBUG(dbgs() << "Emitting segments for function: " << Function.Name << "\n"); FunctionCoverage.Segments = SegmentBuilder().buildSegments(Regions); return FunctionCoverage; @@ -469,6 +473,8 @@ CoverageMapping::getCoverageForExpansion(const ExpansionRecord &Expansion) { } sortNestedRegions(Regions.begin(), Regions.end()); + DEBUG(dbgs() << "Emitting segments for expansion of file " << Expansion.FileID + << "\n"); ExpansionCoverage.Segments = SegmentBuilder().buildSegments(Regions); return ExpansionCoverage; diff --git a/lib/ProfileData/CoverageMappingReader.cpp b/lib/ProfileData/CoverageMappingReader.cpp index 6476d28..d32f1da 100644 --- a/lib/ProfileData/CoverageMappingReader.cpp +++ b/lib/ProfileData/CoverageMappingReader.cpp @@ -173,15 +173,12 @@ std::error_code RawCoverageMappingReader::readMappingRegionsSubArray( } // Read the source range. - uint64_t LineStartDelta, CodeBeforeColumnStart, NumLines, ColumnEnd; + uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd; if (auto Err = readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max())) return Err; - if (auto Err = readULEB128(CodeBeforeColumnStart)) + if (auto Err = readULEB128(ColumnStart)) return Err; - bool HasCodeBefore = CodeBeforeColumnStart & 1; - uint64_t ColumnStart = CodeBeforeColumnStart >> - CounterMappingRegion::EncodingHasCodeBeforeBits; if (ColumnStart > std::numeric_limits<unsigned>::max()) return error(instrprof_error::malformed); if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max())) @@ -214,14 +211,13 @@ std::error_code RawCoverageMappingReader::readMappingRegionsSubArray( }); MappingRegions.push_back(CounterMappingRegion( - C, InferredFileID, LineStart, ColumnStart, LineStart + NumLines, - ColumnEnd, HasCodeBefore, Kind)); - MappingRegions.back().ExpandedFileID = ExpandedFileID; + C, InferredFileID, ExpandedFileID, LineStart, ColumnStart, + LineStart + NumLines, ColumnEnd, Kind)); } return success(); } -std::error_code RawCoverageMappingReader::read(CoverageMappingRecord &Record) { +std::error_code RawCoverageMappingReader::read() { // Read the virtual file mapping. llvm::SmallVector<unsigned, 8> VirtualFileMapping; @@ -287,23 +283,9 @@ std::error_code RawCoverageMappingReader::read(CoverageMappingRecord &Record) { } } - Record.FunctionName = FunctionName; - Record.Filenames = Filenames; - Record.Expressions = Expressions; - Record.MappingRegions = MappingRegions; return success(); } -ObjectFileCoverageMappingReader::ObjectFileCoverageMappingReader( - StringRef FileName) - : CurrentRecord(0) { - auto File = llvm::object::ObjectFile::createObjectFile(FileName); - if (!File) - error(File.getError()); - else - Object = std::move(File.get()); -} - namespace { /// \brief The coverage mapping data for a single function. /// It points to the function's name. @@ -352,7 +334,7 @@ struct SectionData { template <typename T> std::error_code readCoverageMappingData( SectionData &ProfileNames, StringRef Data, - std::vector<ObjectFileCoverageMappingReader::ProfileMappingRecord> &Records, + std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records, std::vector<StringRef> &Filenames) { llvm::DenseSet<T> UniqueFunctionMappingData; @@ -418,7 +400,7 @@ std::error_code readCoverageMappingData( ProfileNames.get(MappingRecord.FunctionNamePtr, MappingRecord.FunctionNameSize, FunctionName)) return Err; - Records.push_back(ObjectFileCoverageMappingReader::ProfileMappingRecord( + Records.push_back(BinaryCoverageReader::ProfileMappingRecord( Version, FunctionName, MappingRecord.FunctionHash, Mapping, FilenamesBegin, Filenames.size() - FilenamesBegin)); } @@ -429,9 +411,12 @@ std::error_code readCoverageMappingData( static const char *TestingFormatMagic = "llvmcovmtestdata"; -static std::error_code decodeTestingFormat(StringRef Data, - SectionData &ProfileNames, - StringRef &CoverageMapping) { +static std::error_code loadTestingFormat(StringRef Data, + SectionData &ProfileNames, + StringRef &CoverageMapping, + uint8_t &BytesInAddress) { + BytesInAddress = 8; + Data = Data.substr(StringRef(TestingFormatMagic).size()); if (Data.size() < 1) return instrprof_error::truncated; @@ -456,98 +441,96 @@ static std::error_code decodeTestingFormat(StringRef Data, return instrprof_error::success; } -ObjectFileCoverageMappingReader::ObjectFileCoverageMappingReader( - std::unique_ptr<MemoryBuffer> &ObjectBuffer, sys::fs::file_magic Type) - : CurrentRecord(0) { - if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic)) { - // This is a special format used for testing. - SectionData ProfileNames; - StringRef CoverageMapping; - if (auto Err = decodeTestingFormat(ObjectBuffer->getBuffer(), ProfileNames, - CoverageMapping)) { - error(Err); - return; - } - error(readCoverageMappingData<uint64_t>(ProfileNames, CoverageMapping, - MappingRecords, Filenames)); - Object = OwningBinary<ObjectFile>(std::unique_ptr<ObjectFile>(), - std::move(ObjectBuffer)); - return; - } - - auto File = object::ObjectFile::createObjectFile( - ObjectBuffer->getMemBufferRef(), Type); - if (!File) - error(File.getError()); - else - Object = OwningBinary<ObjectFile>(std::move(File.get()), - std::move(ObjectBuffer)); -} - -std::error_code ObjectFileCoverageMappingReader::readHeader() { - const ObjectFile *OF = Object.getBinary(); - if (!OF) - return getError(); - auto BytesInAddress = OF->getBytesInAddress(); - if (BytesInAddress != 4 && BytesInAddress != 8) - return error(instrprof_error::malformed); +static std::error_code loadBinaryFormat(MemoryBufferRef ObjectBuffer, + SectionData &ProfileNames, + StringRef &CoverageMapping, + uint8_t &BytesInAddress) { + auto ObjectFileOrErr = object::ObjectFile::createObjectFile(ObjectBuffer); + if (std::error_code EC = ObjectFileOrErr.getError()) + return EC; + auto OF = std::move(ObjectFileOrErr.get()); + BytesInAddress = OF->getBytesInAddress(); // Look for the sections that we are interested in. int FoundSectionCount = 0; - SectionRef ProfileNames, CoverageMapping; + SectionRef NamesSection, CoverageSection; for (const auto &Section : OF->sections()) { StringRef Name; if (auto Err = Section.getName(Name)) return Err; if (Name == "__llvm_prf_names") { - ProfileNames = Section; + NamesSection = Section; } else if (Name == "__llvm_covmap") { - CoverageMapping = Section; + CoverageSection = Section; } else continue; ++FoundSectionCount; } if (FoundSectionCount != 2) - return error(instrprof_error::bad_header); + return instrprof_error::bad_header; // Get the contents of the given sections. - StringRef Data; - if (auto Err = CoverageMapping.getContents(Data)) - return Err; - SectionData ProfileNamesData; - if (auto Err = ProfileNamesData.load(ProfileNames)) - return Err; + if (std::error_code EC = CoverageSection.getContents(CoverageMapping)) + return EC; + if (std::error_code EC = ProfileNames.load(NamesSection)) + return EC; - // Load the data from the found sections. - std::error_code Err; - if (BytesInAddress == 4) - Err = readCoverageMappingData<uint32_t>(ProfileNamesData, Data, - MappingRecords, Filenames); + return std::error_code(); +} + +ErrorOr<std::unique_ptr<BinaryCoverageReader>> +BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer) { + std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader()); + + SectionData Profile; + StringRef Coverage; + uint8_t BytesInAddress; + std::error_code EC; + if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic)) + // This is a special format used for testing. + EC = loadTestingFormat(ObjectBuffer->getBuffer(), Profile, Coverage, + BytesInAddress); else - Err = readCoverageMappingData<uint64_t>(ProfileNamesData, Data, - MappingRecords, Filenames); - if (Err) - return error(Err); + EC = loadBinaryFormat(ObjectBuffer->getMemBufferRef(), Profile, Coverage, + BytesInAddress); + if (EC) + return EC; - return success(); + if (BytesInAddress == 4) + EC = readCoverageMappingData<uint32_t>( + Profile, Coverage, Reader->MappingRecords, Reader->Filenames); + else if (BytesInAddress == 8) + EC = readCoverageMappingData<uint64_t>( + Profile, Coverage, Reader->MappingRecords, Reader->Filenames); + else + return instrprof_error::malformed; + if (EC) + return EC; + return std::move(Reader); } std::error_code -ObjectFileCoverageMappingReader::readNextRecord(CoverageMappingRecord &Record) { +BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) { if (CurrentRecord >= MappingRecords.size()) - return error(instrprof_error::eof); + return instrprof_error::eof; FunctionsFilenames.clear(); Expressions.clear(); MappingRegions.clear(); auto &R = MappingRecords[CurrentRecord]; RawCoverageMappingReader Reader( - R.FunctionName, R.CoverageMapping, - makeArrayRef(Filenames.data() + R.FilenamesBegin, R.FilenamesSize), + R.CoverageMapping, + makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize), FunctionsFilenames, Expressions, MappingRegions); - if (auto Err = Reader.read(Record)) + if (auto Err = Reader.read()) return Err; + + Record.FunctionName = R.FunctionName; Record.FunctionHash = R.FunctionHash; + Record.Filenames = FunctionsFilenames; + Record.Expressions = Expressions; + Record.MappingRegions = MappingRegions; + ++CurrentRecord; - return success(); + return std::error_code(); } diff --git a/lib/ProfileData/CoverageMappingWriter.cpp b/lib/ProfileData/CoverageMappingWriter.cpp index 6969c2a..d90d2f5 100644 --- a/lib/ProfileData/CoverageMappingWriter.cpp +++ b/lib/ProfileData/CoverageMappingWriter.cpp @@ -109,7 +109,7 @@ static void writeCounter(ArrayRef<CounterExpression> Expressions, Counter C, void CoverageMappingWriter::write(raw_ostream &OS) { // Sort the regions in an ascending order by the file id and the starting // location. - std::sort(MappingRegions.begin(), MappingRegions.end()); + std::stable_sort(MappingRegions.begin(), MappingRegions.end()); // Write out the fileid -> filename mapping. encodeULEB128(VirtualFileMapping.size(), OS); @@ -172,11 +172,7 @@ void CoverageMappingWriter::write(raw_ostream &OS) { } assert(I->LineStart >= PrevLineStart); encodeULEB128(I->LineStart - PrevLineStart, OS); - uint64_t CodeBeforeColumnStart = - uint64_t(I->HasCodeBefore) | - (uint64_t(I->ColumnStart) - << CounterMappingRegion::EncodingHasCodeBeforeBits); - encodeULEB128(CodeBeforeColumnStart, OS); + encodeULEB128(I->ColumnStart, OS); assert(I->LineEnd >= I->LineStart); encodeULEB128(I->LineEnd - I->LineStart, OS); encodeULEB128(I->ColumnEnd, OS); diff --git a/lib/ProfileData/InstrProfIndexed.h b/lib/ProfileData/InstrProfIndexed.h index c2bc46c..ebca7b2 100644 --- a/lib/ProfileData/InstrProfIndexed.h +++ b/lib/ProfileData/InstrProfIndexed.h @@ -14,6 +14,7 @@ #ifndef LLVM_LIB_PROFILEDATA_INSTRPROFINDEXED_H #define LLVM_LIB_PROFILEDATA_INSTRPROFINDEXED_H +#include "llvm/Support/Endian.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MD5.h" diff --git a/lib/ProfileData/InstrProfReader.cpp b/lib/ProfileData/InstrProfReader.cpp index 0160a64..01e199d 100644 --- a/lib/ProfileData/InstrProfReader.cpp +++ b/lib/ProfileData/InstrProfReader.cpp @@ -13,10 +13,8 @@ //===----------------------------------------------------------------------===// #include "llvm/ProfileData/InstrProfReader.h" -#include "llvm/ProfileData/InstrProf.h" - #include "InstrProfIndexed.h" - +#include "llvm/ProfileData/InstrProf.h" #include <cassert> using namespace llvm; @@ -27,12 +25,7 @@ setupMemoryBuffer(std::string Path) { MemoryBuffer::getFileOrSTDIN(Path); if (std::error_code EC = BufferOrErr.getError()) return EC; - auto Buffer = std::move(BufferOrErr.get()); - - // Sanity check the file. - if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max()) - return instrprof_error::too_large; - return std::move(Buffer); + return std::move(BufferOrErr.get()); } static std::error_code initializeReader(InstrProfReader &Reader) { @@ -45,10 +38,16 @@ InstrProfReader::create(std::string Path) { auto BufferOrError = setupMemoryBuffer(Path); if (std::error_code EC = BufferOrError.getError()) return EC; + return InstrProfReader::create(std::move(BufferOrError.get())); +} - auto Buffer = std::move(BufferOrError.get()); - std::unique_ptr<InstrProfReader> Result; +ErrorOr<std::unique_ptr<InstrProfReader>> +InstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer) { + // Sanity check the buffer. + if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max()) + return instrprof_error::too_large; + std::unique_ptr<InstrProfReader> Result; // Create the reader. if (IndexedInstrProfReader::hasFormat(*Buffer)) Result.reset(new IndexedInstrProfReader(std::move(Buffer))); @@ -66,21 +65,32 @@ InstrProfReader::create(std::string Path) { return std::move(Result); } -std::error_code IndexedInstrProfReader::create( - std::string Path, std::unique_ptr<IndexedInstrProfReader> &Result) { +ErrorOr<std::unique_ptr<IndexedInstrProfReader>> +IndexedInstrProfReader::create(std::string Path) { // Set up the buffer to read. auto BufferOrError = setupMemoryBuffer(Path); if (std::error_code EC = BufferOrError.getError()) return EC; + return IndexedInstrProfReader::create(std::move(BufferOrError.get())); +} + + +ErrorOr<std::unique_ptr<IndexedInstrProfReader>> +IndexedInstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer) { + // Sanity check the buffer. + if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max()) + return instrprof_error::too_large; - auto Buffer = std::move(BufferOrError.get()); // Create the reader. if (!IndexedInstrProfReader::hasFormat(*Buffer)) return instrprof_error::bad_magic; - Result.reset(new IndexedInstrProfReader(std::move(Buffer))); + auto Result = llvm::make_unique<IndexedInstrProfReader>(std::move(Buffer)); // Initialize the reader and return the result. - return initializeReader(*Result); + if (std::error_code EC = initializeReader(*Result)) + return EC; + + return std::move(Result); } void InstrProfIterator::Increment() { diff --git a/lib/ProfileData/InstrProfWriter.cpp b/lib/ProfileData/InstrProfWriter.cpp index ad1b876..2188543 100644 --- a/lib/ProfileData/InstrProfWriter.cpp +++ b/lib/ProfileData/InstrProfWriter.cpp @@ -13,12 +13,11 @@ //===----------------------------------------------------------------------===// #include "llvm/ProfileData/InstrProfWriter.h" +#include "InstrProfIndexed.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/EndianStream.h" #include "llvm/Support/OnDiskHashTable.h" -#include "InstrProfIndexed.h" - using namespace llvm; namespace { @@ -107,7 +106,7 @@ InstrProfWriter::addFunctionCounts(StringRef FunctionName, return instrprof_error::success; } -void InstrProfWriter::write(raw_fd_ostream &OS) { +std::pair<uint64_t, uint64_t> InstrProfWriter::writeImpl(raw_ostream &OS) { OnDiskChainedHashTableGenerator<InstrProfRecordTrait> Generator; // Populate the hash table generator. @@ -129,7 +128,32 @@ void InstrProfWriter::write(raw_fd_ostream &OS) { // Write the hash table. uint64_t HashTableStart = Generator.Emit(OS); + return std::make_pair(HashTableStartLoc, HashTableStart); +} + +void InstrProfWriter::write(raw_fd_ostream &OS) { + // Write the hash table. + auto TableStart = writeImpl(OS); + // Go back and fill in the hash table start. - OS.seek(HashTableStartLoc); - LE.write<uint64_t>(HashTableStart); + using namespace support; + OS.seek(TableStart.first); + endian::Writer<little>(OS).write<uint64_t>(TableStart.second); +} + +std::unique_ptr<MemoryBuffer> InstrProfWriter::writeBuffer() { + std::string Data; + llvm::raw_string_ostream OS(Data); + // Write the hash table. + auto TableStart = writeImpl(OS); + OS.flush(); + + // Go back and fill in the hash table start. + using namespace support; + uint64_t Bytes = endian::byte_swap<uint64_t, little>(TableStart.second); + Data.replace(TableStart.first, sizeof(uint64_t), (const char *)&Bytes, + sizeof(uint64_t)); + + // Return this in an aligned memory buffer. + return MemoryBuffer::getMemBufferCopy(Data); } diff --git a/lib/ProfileData/SampleProfWriter.cpp b/lib/ProfileData/SampleProfWriter.cpp index 8525045..c95267a 100644 --- a/lib/ProfileData/SampleProfWriter.cpp +++ b/lib/ProfileData/SampleProfWriter.cpp @@ -21,9 +21,9 @@ #include "llvm/ProfileData/SampleProfWriter.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorOr.h" -#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/LineIterator.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Regex.h" using namespace llvm::sampleprof; |