diff options
author | Vedant Kumar <vsk@apple.com> | 2016-05-19 03:54:45 +0000 |
---|---|---|
committer | Vedant Kumar <vsk@apple.com> | 2016-05-19 03:54:45 +0000 |
commit | c77570e06279645eed75c91bf17b05474a707840 (patch) | |
tree | 862b2ee6a8cf66073ceb671e638c77372d89e902 /lib/ProfileData/InstrProfReader.cpp | |
parent | 658bddf628b834c9a307013a7bfd31e803b71930 (diff) |
Retry^3 "[ProfileData] (llvm) Use Error in InstrProf and Coverage, NFC"
Transition InstrProf and Coverage over to the stricter Error/Expected
interface.
Changes since the initial commit:
- Fix error message printing in llvm-profdata.
- Check errors in loadTestingFormat() + annotateAllFunctions().
- Defer error handling in InstrProfIterator to InstrProfReader.
- Remove the base ProfError class to work around an MSVC ICE.
Differential Revision: http://reviews.llvm.org/D19901
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270020 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ProfileData/InstrProfReader.cpp')
-rw-r--r-- | lib/ProfileData/InstrProfReader.cpp | 175 |
1 files changed, 86 insertions, 89 deletions
diff --git a/lib/ProfileData/InstrProfReader.cpp b/lib/ProfileData/InstrProfReader.cpp index 0828bb2c3fc..2678ac28561 100644 --- a/lib/ProfileData/InstrProfReader.cpp +++ b/lib/ProfileData/InstrProfReader.cpp @@ -18,33 +18,33 @@ using namespace llvm; -static ErrorOr<std::unique_ptr<MemoryBuffer>> +static Expected<std::unique_ptr<MemoryBuffer>> setupMemoryBuffer(std::string Path) { ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getFileOrSTDIN(Path); if (std::error_code EC = BufferOrErr.getError()) - return EC; + return errorCodeToError(EC); return std::move(BufferOrErr.get()); } -static std::error_code initializeReader(InstrProfReader &Reader) { +static Error initializeReader(InstrProfReader &Reader) { return Reader.readHeader(); } -ErrorOr<std::unique_ptr<InstrProfReader>> +Expected<std::unique_ptr<InstrProfReader>> InstrProfReader::create(std::string Path) { // Set up the buffer to read. auto BufferOrError = setupMemoryBuffer(Path); - if (std::error_code EC = BufferOrError.getError()) - return EC; + if (Error E = BufferOrError.takeError()) + return std::move(E); return InstrProfReader::create(std::move(BufferOrError.get())); } -ErrorOr<std::unique_ptr<InstrProfReader>> +Expected<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; + return make_error<InstrProfError>(instrprof_error::too_large); std::unique_ptr<InstrProfReader> Result; // Create the reader. @@ -57,46 +57,49 @@ InstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer) { else if (TextInstrProfReader::hasFormat(*Buffer)) Result.reset(new TextInstrProfReader(std::move(Buffer))); else - return instrprof_error::unrecognized_format; + return make_error<InstrProfError>(instrprof_error::unrecognized_format); // Initialize the reader and return the result. - if (std::error_code EC = initializeReader(*Result)) - return EC; + if (Error E = initializeReader(*Result)) + return std::move(E); return std::move(Result); } -ErrorOr<std::unique_ptr<IndexedInstrProfReader>> +Expected<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; + if (Error E = BufferOrError.takeError()) + return std::move(E); return IndexedInstrProfReader::create(std::move(BufferOrError.get())); } -ErrorOr<std::unique_ptr<IndexedInstrProfReader>> +Expected<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; + return make_error<InstrProfError>(instrprof_error::too_large); // Create the reader. if (!IndexedInstrProfReader::hasFormat(*Buffer)) - return instrprof_error::bad_magic; + return make_error<InstrProfError>(instrprof_error::bad_magic); auto Result = llvm::make_unique<IndexedInstrProfReader>(std::move(Buffer)); // Initialize the reader and return the result. - if (std::error_code EC = initializeReader(*Result)) - return EC; + if (Error E = initializeReader(*Result)) + return std::move(E); return std::move(Result); } void InstrProfIterator::Increment() { - if (Reader->readNextRecord(Record)) + if (auto E = Reader->readNextRecord(Record)) { + // Handle errors in the reader. + InstrProfError::take(std::move(E)); *this = InstrProfIterator(); + } } bool TextInstrProfReader::hasFormat(const MemoryBuffer &Buffer) { @@ -112,7 +115,7 @@ bool TextInstrProfReader::hasFormat(const MemoryBuffer &Buffer) { // Read the profile variant flag from the header: ":FE" means this is a FE // generated profile. ":IR" means this is an IR level profile. Other strings // with a leading ':' will be reported an error format. -std::error_code TextInstrProfReader::readHeader() { +Error TextInstrProfReader::readHeader() { Symtab.reset(new InstrProfSymtab()); bool IsIRInstr = false; if (!Line->startswith(":")) { @@ -125,14 +128,14 @@ std::error_code TextInstrProfReader::readHeader() { else if (Str.equals_lower("fe")) IsIRInstr = false; else - return instrprof_error::bad_header; + return error(instrprof_error::bad_header); ++Line; IsIRLevelProfile = IsIRInstr; return success(); } -std::error_code +Error TextInstrProfReader::readValueProfileData(InstrProfRecord &Record) { #define CHECK_LINE_END(Line) \ @@ -196,7 +199,7 @@ TextInstrProfReader::readValueProfileData(InstrProfRecord &Record) { #undef VP_READ_ADVANCE } -std::error_code TextInstrProfReader::readNextRecord(InstrProfRecord &Record) { +Error TextInstrProfReader::readNextRecord(InstrProfRecord &Record) { // Skip empty lines and comments. while (!Line.is_at_end() && (Line->empty() || Line->startswith("#"))) ++Line; @@ -238,8 +241,8 @@ std::error_code TextInstrProfReader::readNextRecord(InstrProfRecord &Record) { } // Check if value profile data exists and read it if so. - if (std::error_code EC = readValueProfileData(Record)) - return EC; + if (Error E = readValueProfileData(Record)) + return E; // This is needed to avoid two pass parsing because llvm-profdata // does dumping while reading. @@ -258,7 +261,7 @@ bool RawInstrProfReader<IntPtrT>::hasFormat(const MemoryBuffer &DataBuffer) { } template <class IntPtrT> -std::error_code RawInstrProfReader<IntPtrT>::readHeader() { +Error RawInstrProfReader<IntPtrT>::readHeader() { if (!hasFormat(*DataBuffer)) return error(instrprof_error::bad_magic); if (DataBuffer->getBufferSize() < sizeof(RawInstrProf::Header)) @@ -270,26 +273,25 @@ std::error_code RawInstrProfReader<IntPtrT>::readHeader() { } template <class IntPtrT> -std::error_code -RawInstrProfReader<IntPtrT>::readNextHeader(const char *CurrentPos) { +Error RawInstrProfReader<IntPtrT>::readNextHeader(const char *CurrentPos) { const char *End = DataBuffer->getBufferEnd(); // Skip zero padding between profiles. while (CurrentPos != End && *CurrentPos == 0) ++CurrentPos; // If there's nothing left, we're done. if (CurrentPos == End) - return instrprof_error::eof; + return make_error<InstrProfError>(instrprof_error::eof); // If there isn't enough space for another header, this is probably just // garbage at the end of the file. if (CurrentPos + sizeof(RawInstrProf::Header) > End) - return instrprof_error::malformed; + return make_error<InstrProfError>(instrprof_error::malformed); // The writer ensures each profile is padded to start at an aligned address. if (reinterpret_cast<size_t>(CurrentPos) % alignOf<uint64_t>()) - return instrprof_error::malformed; + return make_error<InstrProfError>(instrprof_error::malformed); // The magic should have the same byte order as in the previous header. uint64_t Magic = *reinterpret_cast<const uint64_t *>(CurrentPos); if (Magic != swap(RawInstrProf::getMagic<IntPtrT>())) - return instrprof_error::bad_magic; + return make_error<InstrProfError>(instrprof_error::bad_magic); // There's another profile to read, so we need to process the header. auto *Header = reinterpret_cast<const RawInstrProf::Header *>(CurrentPos); @@ -297,11 +299,9 @@ RawInstrProfReader<IntPtrT>::readNextHeader(const char *CurrentPos) { } template <class IntPtrT> -std::error_code -RawInstrProfReader<IntPtrT>::createSymtab(InstrProfSymtab &Symtab) { - std::error_code EC = Symtab.create(StringRef(NamesStart, NamesSize)); - if (EC) - return EC; +Error RawInstrProfReader<IntPtrT>::createSymtab(InstrProfSymtab &Symtab) { + if (Error E = Symtab.create(StringRef(NamesStart, NamesSize))) + return error(std::move(E)); for (const RawInstrProf::ProfileData<IntPtrT> *I = Data; I != DataEnd; ++I) { const IntPtrT FPtr = swap(I->FunctionPointer); if (!FPtr) @@ -313,8 +313,8 @@ RawInstrProfReader<IntPtrT>::createSymtab(InstrProfSymtab &Symtab) { } template <class IntPtrT> -std::error_code -RawInstrProfReader<IntPtrT>::readHeader(const RawInstrProf::Header &Header) { +Error RawInstrProfReader<IntPtrT>::readHeader( + const RawInstrProf::Header &Header) { Version = swap(Header.Version); if (GET_VERSION(Version) != RawInstrProf::Version) return error(instrprof_error::unsupported_version); @@ -346,28 +346,27 @@ RawInstrProfReader<IntPtrT>::readHeader(const RawInstrProf::Header &Header) { ValueDataStart = reinterpret_cast<const uint8_t *>(Start + ValueDataOffset); std::unique_ptr<InstrProfSymtab> NewSymtab = make_unique<InstrProfSymtab>(); - if (auto EC = createSymtab(*NewSymtab.get())) - return EC; + if (Error E = createSymtab(*NewSymtab.get())) + return E; Symtab = std::move(NewSymtab); return success(); } template <class IntPtrT> -std::error_code RawInstrProfReader<IntPtrT>::readName(InstrProfRecord &Record) { +Error RawInstrProfReader<IntPtrT>::readName(InstrProfRecord &Record) { Record.Name = getName(Data->NameRef); return success(); } template <class IntPtrT> -std::error_code RawInstrProfReader<IntPtrT>::readFuncHash( - InstrProfRecord &Record) { +Error RawInstrProfReader<IntPtrT>::readFuncHash(InstrProfRecord &Record) { Record.Hash = swap(Data->FuncHash); return success(); } template <class IntPtrT> -std::error_code RawInstrProfReader<IntPtrT>::readRawCounts( +Error RawInstrProfReader<IntPtrT>::readRawCounts( InstrProfRecord &Record) { uint32_t NumCounters = swap(Data->NumCounters); IntPtrT CounterPtr = Data->CounterPtr; @@ -394,8 +393,8 @@ std::error_code RawInstrProfReader<IntPtrT>::readRawCounts( } template <class IntPtrT> -std::error_code -RawInstrProfReader<IntPtrT>::readValueProfilingData(InstrProfRecord &Record) { +Error RawInstrProfReader<IntPtrT>::readValueProfilingData( + InstrProfRecord &Record) { Record.clearValueData(); CurValueDataSize = 0; @@ -407,13 +406,13 @@ RawInstrProfReader<IntPtrT>::readValueProfilingData(InstrProfRecord &Record) { if (!NumValueKinds) return success(); - ErrorOr<std::unique_ptr<ValueProfData>> VDataPtrOrErr = + Expected<std::unique_ptr<ValueProfData>> VDataPtrOrErr = ValueProfData::getValueProfData( ValueDataStart, (const unsigned char *)DataBuffer->getBufferEnd(), getDataEndianness()); - if (VDataPtrOrErr.getError()) - return VDataPtrOrErr.getError(); + if (Error E = VDataPtrOrErr.takeError()) + return E; // Note that besides deserialization, this also performs the conversion for // indirect call targets. The function pointers from the raw profile are @@ -424,28 +423,27 @@ RawInstrProfReader<IntPtrT>::readValueProfilingData(InstrProfRecord &Record) { } template <class IntPtrT> -std::error_code -RawInstrProfReader<IntPtrT>::readNextRecord(InstrProfRecord &Record) { +Error RawInstrProfReader<IntPtrT>::readNextRecord(InstrProfRecord &Record) { if (atEnd()) // At this point, ValueDataStart field points to the next header. - if (std::error_code EC = readNextHeader(getNextHeaderPos())) - return EC; + if (Error E = readNextHeader(getNextHeaderPos())) + return E; // Read name ad set it in Record. - if (std::error_code EC = readName(Record)) - return EC; + if (Error E = readName(Record)) + return E; // Read FuncHash and set it in Record. - if (std::error_code EC = readFuncHash(Record)) - return EC; + if (Error E = readFuncHash(Record)) + return E; // Read raw counts and set Record. - if (std::error_code EC = readRawCounts(Record)) - return EC; + if (Error E = readRawCounts(Record)) + return E; // Read value data and set Record. - if (std::error_code EC = readValueProfilingData(Record)) - return EC; + if (Error E = readValueProfilingData(Record)) + return E; // Iterate. advanceData(); @@ -467,10 +465,10 @@ typedef InstrProfLookupTrait::offset_type offset_type; bool InstrProfLookupTrait::readValueProfilingData( const unsigned char *&D, const unsigned char *const End) { - ErrorOr<std::unique_ptr<ValueProfData>> VDataPtrOrErr = + Expected<std::unique_ptr<ValueProfData>> VDataPtrOrErr = ValueProfData::getValueProfData(D, End, ValueProfDataEndianness); - if (VDataPtrOrErr.getError()) + if (VDataPtrOrErr.takeError()) return false; VDataPtrOrErr.get()->deserializeTo(DataBuffer.back(), nullptr); @@ -526,31 +524,31 @@ data_type InstrProfLookupTrait::ReadData(StringRef K, const unsigned char *D, } template <typename HashTableImpl> -std::error_code InstrProfReaderIndex<HashTableImpl>::getRecords( +Error InstrProfReaderIndex<HashTableImpl>::getRecords( StringRef FuncName, ArrayRef<InstrProfRecord> &Data) { auto Iter = HashTable->find(FuncName); if (Iter == HashTable->end()) - return instrprof_error::unknown_function; + return make_error<InstrProfError>(instrprof_error::unknown_function); Data = (*Iter); if (Data.empty()) - return instrprof_error::malformed; + return make_error<InstrProfError>(instrprof_error::malformed); - return instrprof_error::success; + return Error::success(); } template <typename HashTableImpl> -std::error_code InstrProfReaderIndex<HashTableImpl>::getRecords( +Error InstrProfReaderIndex<HashTableImpl>::getRecords( ArrayRef<InstrProfRecord> &Data) { if (atEnd()) - return instrprof_error::eof; + return make_error<InstrProfError>(instrprof_error::eof); Data = *RecordIterator; if (Data.empty()) - return instrprof_error::malformed; + return make_error<InstrProfError>(instrprof_error::malformed); - return instrprof_error::success; + return Error::success(); } template <typename HashTableImpl> @@ -609,7 +607,7 @@ IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version, } } -std::error_code IndexedInstrProfReader::readHeader() { +Error IndexedInstrProfReader::readHeader() { const unsigned char *Start = (const unsigned char *)DataBuffer->getBufferStart(); const unsigned char *Cur = Start; @@ -661,13 +659,13 @@ InstrProfSymtab &IndexedInstrProfReader::getSymtab() { return *Symtab.get(); } -ErrorOr<InstrProfRecord> +Expected<InstrProfRecord> IndexedInstrProfReader::getInstrProfRecord(StringRef FuncName, uint64_t FuncHash) { ArrayRef<InstrProfRecord> Data; - std::error_code EC = Index->getRecords(FuncName, Data); - if (EC != instrprof_error::success) - return EC; + Error Err = Index->getRecords(FuncName, Data); + if (Err) + return std::move(Err); // Found it. Look for counters with the right hash. for (unsigned I = 0, E = Data.size(); I < E; ++I) { // Check for a match and fill the vector if there is one. @@ -678,26 +676,25 @@ IndexedInstrProfReader::getInstrProfRecord(StringRef FuncName, return error(instrprof_error::hash_mismatch); } -std::error_code -IndexedInstrProfReader::getFunctionCounts(StringRef FuncName, uint64_t FuncHash, - std::vector<uint64_t> &Counts) { - ErrorOr<InstrProfRecord> Record = getInstrProfRecord(FuncName, FuncHash); - if (std::error_code EC = Record.getError()) - return EC; +Error IndexedInstrProfReader::getFunctionCounts(StringRef FuncName, + uint64_t FuncHash, + std::vector<uint64_t> &Counts) { + Expected<InstrProfRecord> Record = getInstrProfRecord(FuncName, FuncHash); + if (Error E = Record.takeError()) + return error(std::move(E)); Counts = Record.get().Counts; return success(); } -std::error_code IndexedInstrProfReader::readNextRecord( - InstrProfRecord &Record) { +Error IndexedInstrProfReader::readNextRecord(InstrProfRecord &Record) { static unsigned RecordIndex = 0; ArrayRef<InstrProfRecord> Data; - std::error_code EC = Index->getRecords(Data); - if (EC != instrprof_error::success) - return error(EC); + Error E = Index->getRecords(Data); + if (E) + return error(std::move(E)); Record = Data[RecordIndex++]; if (RecordIndex >= Data.size()) { |