aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ProfileData
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2015-03-23 12:10:34 -0700
committerStephen Hines <srhines@google.com>2015-03-23 12:10:34 -0700
commitebe69fe11e48d322045d5949c83283927a0d790b (patch)
treec92f1907a6b8006628a4b01615f38264d29834ea /lib/ProfileData
parentb7d2e72b02a4cb8034f32f8247a2558d2434e121 (diff)
downloadexternal_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.txt3
-rw-r--r--lib/ProfileData/CoverageMapping.cpp110
-rw-r--r--lib/ProfileData/CoverageMappingReader.cpp161
-rw-r--r--lib/ProfileData/CoverageMappingWriter.cpp8
-rw-r--r--lib/ProfileData/InstrProfIndexed.h1
-rw-r--r--lib/ProfileData/InstrProfReader.cpp42
-rw-r--r--lib/ProfileData/InstrProfWriter.cpp34
-rw-r--r--lib/ProfileData/SampleProfWriter.cpp2
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;