Index: include/llvm/ProfileData/SampleProf.h =================================================================== --- include/llvm/ProfileData/SampleProf.h +++ include/llvm/ProfileData/SampleProf.h @@ -28,15 +28,12 @@ #include #include #include -#include #include namespace llvm { class raw_ostream; -const std::error_category &sampleprof_category(); - enum class sampleprof_error { success = 0, bad_magic, @@ -52,9 +49,7 @@ ostream_seek_unsupported }; -inline std::error_code make_error_code(sampleprof_error E) { - return std::error_code(static_cast(E), sampleprof_category()); -} +Error createSampleProfError(sampleprof_error E); inline sampleprof_error MergeResult(sampleprof_error &Accumulator, sampleprof_error Result) { Index: include/llvm/ProfileData/SampleProfReader.h =================================================================== --- include/llvm/ProfileData/SampleProfReader.h +++ include/llvm/ProfileData/SampleProfReader.h @@ -219,7 +219,6 @@ #include "llvm/ProfileData/GCOV.h" #include "llvm/ProfileData/SampleProf.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/ErrorOr.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SymbolRemappingReader.h" #include @@ -271,10 +270,10 @@ virtual ~SampleProfileReader() = default; /// Read and validate the file header. - virtual std::error_code readHeader() = 0; + virtual Error readHeader() = 0; /// Read sample profiles from the associated file. - virtual std::error_code read() = 0; + virtual Error read() = 0; /// Print the profile for \p FName on stream \p OS. void dumpFunctionProfile(StringRef FName, raw_ostream &OS = dbgs()); @@ -312,12 +311,19 @@ LineNumber, Msg)); } + void reportError(int64_t LineNumber, const Error &E) const { + std::string Message; + raw_string_ostream OS(Message); + OS << E; + reportError(LineNumber, OS.str()); + } + /// Create a sample profile reader appropriate to the file format. - static ErrorOr> + static Expected> create(const Twine &Filename, LLVMContext &C); /// Create a sample profile reader from the supplied memory buffer. - static ErrorOr> + static Expected> create(std::unique_ptr &B, LLVMContext &C); /// Return the profile summary. @@ -362,10 +368,10 @@ : SampleProfileReader(std::move(B), C, SPF_Text) {} /// Read and validate the file header. - std::error_code readHeader() override { return sampleprof_error::success; } + Error readHeader() override { return Error::success(); } /// Read sample profiles from the associated file. - std::error_code read() override; + Error read() override; /// Return true if \p Buffer is in the format supported by this class. static bool hasFormat(const MemoryBuffer &Buffer); @@ -378,10 +384,10 @@ : SampleProfileReader(std::move(B), C, Format) {} /// Read and validate the file header. - virtual std::error_code readHeader() override; + virtual Error readHeader() override; /// Read sample profiles from the associated file. - std::error_code read() override; + Error read() override; protected: /// Read a numeric value of type T from the profile. @@ -390,11 +396,11 @@ /// EC is set. /// /// \returns the read value. - template ErrorOr readNumber(); + template Expected readNumber(); /// Read a numeric value of type T from the profile. The value is saved /// without encoded. - template ErrorOr readUnencodedNumber(); + template Expected readUnencodedNumber(); /// Read a string from the profile. /// @@ -402,19 +408,19 @@ /// EC is set. /// /// \returns the read value. - ErrorOr readString(); + Expected readString(); /// Read the string index and check whether it overflows the table. - template inline ErrorOr readStringIndex(T &Table); + template inline Expected readStringIndex(T &Table); /// Return true if we've reached the end of file. bool at_eof() const { return Data >= End; } /// Read the next function profile instance. - std::error_code readFuncProfile(); + Error readFuncProfile(); /// Read the contents of the given profile instance. - std::error_code readProfile(FunctionSamples &FProfile); + Error readProfile(FunctionSamples &FProfile); /// Points to the current location in the buffer. const uint8_t *Data = nullptr; @@ -423,27 +429,27 @@ const uint8_t *End = nullptr; private: - std::error_code readSummaryEntry(std::vector &Entries); - virtual std::error_code verifySPMagic(uint64_t Magic) = 0; + Error readSummaryEntry(std::vector &Entries); + virtual Error verifySPMagic(uint64_t Magic) = 0; /// Read profile summary. - std::error_code readSummary(); + Error readSummary(); /// Read the whole name table. - virtual std::error_code readNameTable() = 0; + virtual Error readNameTable() = 0; /// Read a string indirectly via the name table. - virtual ErrorOr readStringFromTable() = 0; + virtual Expected readStringFromTable() = 0; }; class SampleProfileReaderRawBinary : public SampleProfileReaderBinary { private: /// Function name table. std::vector NameTable; - virtual std::error_code verifySPMagic(uint64_t Magic) override; - virtual std::error_code readNameTable() override; + virtual Error verifySPMagic(uint64_t Magic) override; + virtual Error readNameTable() override; /// Read a string indirectly via the name table. - virtual ErrorOr readStringFromTable() override; + virtual Expected readStringFromTable() override; public: SampleProfileReaderRawBinary(std::unique_ptr B, LLVMContext &C) @@ -462,12 +468,12 @@ DenseMap FuncOffsetTable; /// The set containing the functions to use when compiling a module. DenseSet FuncsToUse; - virtual std::error_code verifySPMagic(uint64_t Magic) override; - virtual std::error_code readNameTable() override; + virtual Error verifySPMagic(uint64_t Magic) override; + virtual Error readNameTable() override; /// Read a string indirectly via the name table. - virtual ErrorOr readStringFromTable() override; - virtual std::error_code readHeader() override; - std::error_code readFuncOffsetTable(); + virtual Expected readStringFromTable() override; + virtual Error readHeader() override; + Error readFuncOffsetTable(); public: SampleProfileReaderCompactBinary(std::unique_ptr B, @@ -478,7 +484,7 @@ static bool hasFormat(const MemoryBuffer &Buffer); /// Read samples only for functions to use. - std::error_code read() override; + Error read() override; /// Collect functions to be used when compiling Module \p M. void collectFuncsToUse(const Module &M) override; @@ -506,25 +512,25 @@ GcovBuffer(Buffer.get()) {} /// Read and validate the file header. - std::error_code readHeader() override; + Error readHeader() override; /// Read sample profiles from the associated file. - std::error_code read() override; + Error read() override; /// Return true if \p Buffer is in the format supported by this class. static bool hasFormat(const MemoryBuffer &Buffer); protected: - std::error_code readNameTable(); - std::error_code readOneFunctionProfile(const InlineCallStack &InlineStack, - bool Update, uint32_t Offset); - std::error_code readFunctionProfiles(); - std::error_code skipNextWord(); - template ErrorOr readNumber(); - ErrorOr readString(); + Error readNameTable(); + Error readOneFunctionProfile(const InlineCallStack &InlineStack, bool Update, + uint32_t Offset); + Error readFunctionProfiles(); + Error skipNextWord(); + template Expected readNumber(); + Expected readString(); /// Read the section tag and check that it's the same as \p Expected. - std::error_code readSectionTag(uint32_t Expected); + Error readSectionTag(uint32_t Expected); /// GCOV buffer containing the profile. GCOVBuffer GcovBuffer; @@ -555,15 +561,15 @@ /// Create a remapped sample profile from the given remapping file and /// underlying samples. - static ErrorOr> + static Expected> create(const Twine &Filename, LLVMContext &C, std::unique_ptr Underlying); /// Read and validate the file header. - std::error_code readHeader() override { return sampleprof_error::success; } + Error readHeader() override { return Error::success(); } /// Read remapping file and apply it to the sample profile. - std::error_code read() override; + Error read() override; /// Return the samples collected for function \p F. FunctionSamples *getSamplesFor(StringRef FunctionName) override; Index: include/llvm/ProfileData/SampleProfWriter.h =================================================================== --- include/llvm/ProfileData/SampleProfWriter.h +++ include/llvm/ProfileData/SampleProfWriter.h @@ -17,13 +17,12 @@ #include "llvm/ADT/StringRef.h" #include "llvm/IR/ProfileSummary.h" #include "llvm/ProfileData/SampleProf.h" -#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/Error.h" #include "llvm/Support/raw_ostream.h" #include #include #include #include -#include namespace llvm { namespace sampleprof { @@ -36,24 +35,24 @@ /// Write sample profiles in \p S. /// /// \returns status code of the file update operation. - virtual std::error_code write(const FunctionSamples &S) = 0; + virtual Error write(const FunctionSamples &S) = 0; /// Write all the sample profiles in the given map of samples. /// /// \returns status code of the file update operation. - virtual std::error_code write(const StringMap &ProfileMap); + virtual Error write(const StringMap &ProfileMap); raw_ostream &getOutputStream() { return *OutputStream; } /// Profile writer factory. /// /// Create a new file writer based on the value of \p Format. - static ErrorOr> + static Expected> create(StringRef Filename, SampleProfileFormat Format); /// Create a new stream writer based on the value of \p Format. /// For testing. - static ErrorOr> + static Expected> create(std::unique_ptr &OS, SampleProfileFormat Format); protected: @@ -61,8 +60,7 @@ : OutputStream(std::move(OS)) {} /// Write a file header for the profile file. - virtual std::error_code - writeHeader(const StringMap &ProfileMap) = 0; + virtual Error writeHeader(const StringMap &ProfileMap) = 0; /// Output stream where to emit the profile to. std::unique_ptr OutputStream; @@ -77,15 +75,14 @@ /// Sample-based profile writer (text format). class SampleProfileWriterText : public SampleProfileWriter { public: - std::error_code write(const FunctionSamples &S) override; + Error write(const FunctionSamples &S) override; protected: SampleProfileWriterText(std::unique_ptr &OS) : SampleProfileWriter(OS), Indent(0) {} - std::error_code - writeHeader(const StringMap &ProfileMap) override { - return sampleprof_error::success; + Error writeHeader(const StringMap &ProfileMap) override { + return Error::success(); } private: @@ -94,7 +91,7 @@ /// This is used when printing inlined callees. unsigned Indent; - friend ErrorOr> + friend Expected> SampleProfileWriter::create(std::unique_ptr &OS, SampleProfileFormat Format); }; @@ -102,18 +99,18 @@ /// Sample-based profile writer (binary format). class SampleProfileWriterBinary : public SampleProfileWriter { public: - virtual std::error_code write(const FunctionSamples &S) override; + virtual Error write(const FunctionSamples &S) override; SampleProfileWriterBinary(std::unique_ptr &OS) : SampleProfileWriter(OS) {} protected: - virtual std::error_code writeNameTable() = 0; - virtual std::error_code writeMagicIdent() = 0; - virtual std::error_code + virtual Error writeNameTable() = 0; + virtual Error writeMagicIdent() = 0; + virtual Error writeHeader(const StringMap &ProfileMap) override; - std::error_code writeSummary(); - std::error_code writeNameIdx(StringRef FName); - std::error_code writeBody(const FunctionSamples &S); + Error writeSummary(); + Error writeNameIdx(StringRef FName); + Error writeBody(const FunctionSamples &S); inline void stablizeNameTable(std::set &V); MapVector NameTable; @@ -122,7 +119,7 @@ void addName(StringRef FName); void addNames(const FunctionSamples &S); - friend ErrorOr> + friend Expected> SampleProfileWriter::create(std::unique_ptr &OS, SampleProfileFormat Format); }; @@ -131,8 +128,8 @@ using SampleProfileWriterBinary::SampleProfileWriterBinary; protected: - virtual std::error_code writeNameTable() override; - virtual std::error_code writeMagicIdent() override; + virtual Error writeNameTable() override; + virtual Error writeMagicIdent() override; }; // CompactBinary is a compact format of binary profile which both reduces @@ -169,9 +166,8 @@ using SampleProfileWriterBinary::SampleProfileWriterBinary; public: - virtual std::error_code write(const FunctionSamples &S) override; - virtual std::error_code - write(const StringMap &ProfileMap) override; + virtual Error write(const FunctionSamples &S) override; + virtual Error write(const StringMap &ProfileMap) override; protected: /// The table mapping from function name to the offset of its FunctionSample @@ -180,11 +176,11 @@ /// The offset of the slot to be filled with the offset of FuncOffsetTable /// towards profile start. uint64_t TableOffset; - virtual std::error_code writeNameTable() override; - virtual std::error_code writeMagicIdent() override; - virtual std::error_code + virtual Error writeNameTable() override; + virtual Error writeMagicIdent() override; + virtual Error writeHeader(const StringMap &ProfileMap) override; - std::error_code writeFuncOffsetTable(); + Error writeFuncOffsetTable(); }; } // end namespace sampleprof Index: lib/ProfileData/SampleProf.cpp =================================================================== --- lib/ProfileData/SampleProf.cpp +++ lib/ProfileData/SampleProf.cpp @@ -16,11 +16,11 @@ #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/raw_ostream.h" #include -#include using namespace llvm; using namespace sampleprof; @@ -31,54 +31,70 @@ DenseMap FunctionSamples::GUIDToFuncNameMap; Module *FunctionSamples::CurrentModule; } // namespace sampleprof -} // namespace llvm namespace { -// FIXME: This class is only here to support the transition to llvm::Error. It -// will be removed once this transition is complete. Clients should prefer to -// deal with the Error value directly, rather than converting to error_code. -class SampleProfErrorCategoryType : public std::error_category { - const char *name() const noexcept override { return "llvm.sampleprof"; } +class SampleProfError : public ErrorInfo { +public: + static char ID; - std::string message(int IE) const override { - sampleprof_error E = static_cast(IE); + SampleProfError(sampleprof_error E) : E(E) {} + + void log(raw_ostream &OS) const override { switch (E) { case sampleprof_error::success: - return "Success"; + OS << "Success"; + break; case sampleprof_error::bad_magic: - return "Invalid sample profile data (bad magic)"; + OS << "Invalid sample profile data (bad magic)"; + break; case sampleprof_error::unsupported_version: - return "Unsupported sample profile format version"; + OS << "Unsupported sample profile format version"; + break; case sampleprof_error::too_large: - return "Too much profile data"; + OS << "Too much profile data"; + break; case sampleprof_error::truncated: - return "Truncated profile data"; + OS << "Truncated profile data"; + break; case sampleprof_error::malformed: - return "Malformed sample profile data"; + OS << "Malformed sample profile data"; + break; case sampleprof_error::unrecognized_format: - return "Unrecognized sample profile encoding format"; + OS << "Unrecognized sample profile encoding format"; + break; case sampleprof_error::unsupported_writing_format: - return "Profile encoding format unsupported for writing operations"; + OS << "Profile encoding format unsupported for writing operations"; + break; case sampleprof_error::truncated_name_table: - return "Truncated function name table"; + OS << "Truncated function name table"; + break; case sampleprof_error::not_implemented: - return "Unimplemented feature"; + OS << "Unimplemented feature"; + break; case sampleprof_error::counter_overflow: - return "Counter overflow"; + OS << "Counter overflow"; + break; case sampleprof_error::ostream_seek_unsupported: - return "Ostream does not support seek"; + OS << "Ostream does not support seek"; + break; } - llvm_unreachable("A value of sampleprof_error has no message."); } + + std::error_code convertToErrorCode() const override { + llvm_unreachable("Not implemented"); + } + +private: + sampleprof_error E; }; +char SampleProfError::ID = 0; + } // end anonymous namespace -static ManagedStatic ErrorCategory; - -const std::error_category &llvm::sampleprof_category() { - return *ErrorCategory; +Error createSampleProfError(sampleprof_error E) { + return Error(llvm::make_unique(E)); } void LineLocation::print(raw_ostream &OS) const { @@ -190,3 +206,4 @@ #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void FunctionSamples::dump() const { print(dbgs(), 0); } #endif +} // namespace llvm Index: lib/ProfileData/SampleProfReader.cpp =================================================================== --- lib/ProfileData/SampleProfReader.cpp +++ lib/ProfileData/SampleProfReader.cpp @@ -26,7 +26,6 @@ #include "llvm/IR/ProfileSummary.h" #include "llvm/ProfileData/ProfileCommon.h" #include "llvm/ProfileData/SampleProf.h" -#include "llvm/Support/ErrorOr.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/LineIterator.h" #include "llvm/Support/MD5.h" @@ -190,7 +189,7 @@ /// the expected format. /// /// \returns true if the file was loaded successfully, false otherwise. -std::error_code SampleProfileReaderText::read() { +Error SampleProfileReaderText::read() { line_iterator LineIt(*Buffer, /*SkipBlanks=*/true, '#'); sampleprof_error Result = sampleprof_error::success; @@ -217,7 +216,7 @@ if (!ParseHead(*LineIt, FName, NumSamples, NumHeadSamples)) { reportError(LineIt.line_number(), "Expected 'mangled_name:NUM:NUM', found " + *LineIt); - return sampleprof_error::malformed; + return createSampleProfError(sampleprof_error::malformed); } Profiles[FName] = FunctionSamples(); FunctionSamples &FProfile = Profiles[FName]; @@ -237,7 +236,7 @@ reportError(LineIt.line_number(), "Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found " + *LineIt); - return sampleprof_error::malformed; + return createSampleProfError(sampleprof_error::malformed); } if (IsCallsite) { while (InlineStack.size() > Depth) { @@ -263,10 +262,11 @@ } } } - if (Result == sampleprof_error::success) - computeSummary(); + if (Result != sampleprof_error::success) + return createSampleProfError(Result); - return Result; + computeSummary(); + return Error::success(); } bool SampleProfileReaderText::hasFormat(const MemoryBuffer &Buffer) { @@ -285,9 +285,9 @@ return result; } -template ErrorOr SampleProfileReaderBinary::readNumber() { +template Expected SampleProfileReaderBinary::readNumber() { unsigned NumBytesRead = 0; - std::error_code EC; + sampleprof_error EC; uint64_t Val = decodeULEB128(Data, &NumBytesRead); if (Val > std::numeric_limits::max()) @@ -297,22 +297,22 @@ else EC = sampleprof_error::success; - if (EC) { - reportError(0, EC.message()); - return EC; + if (EC != sampleprof_error::success) { + Error E = createSampleProfError(EC); + reportError(0, E); + return std::move(E); } Data += NumBytesRead; return static_cast(Val); } -ErrorOr SampleProfileReaderBinary::readString() { - std::error_code EC; +Expected SampleProfileReaderBinary::readString() { StringRef Str(reinterpret_cast(Data)); if (Data + Str.size() + 1 > End) { - EC = sampleprof_error::truncated; - reportError(0, EC.message()); - return EC; + Error E = createSampleProfError(sampleprof_error::truncated); + reportError(0, E); + return std::move(E); } Data += Str.size() + 1; @@ -320,13 +320,11 @@ } template -ErrorOr SampleProfileReaderBinary::readUnencodedNumber() { - std::error_code EC; - +Expected SampleProfileReaderBinary::readUnencodedNumber() { if (Data + sizeof(T) > End) { - EC = sampleprof_error::truncated; - reportError(0, EC.message()); - return EC; + Error E = createSampleProfError(sampleprof_error::truncated); + reportError(0, E); + return std::move(E); } using namespace support; @@ -335,73 +333,70 @@ } template -inline ErrorOr SampleProfileReaderBinary::readStringIndex(T &Table) { - std::error_code EC; +inline Expected SampleProfileReaderBinary::readStringIndex(T &Table) { auto Idx = readNumber(); - if (std::error_code EC = Idx.getError()) - return EC; + if (!Idx) + return Idx.takeError(); if (*Idx >= Table.size()) - return sampleprof_error::truncated_name_table; + return createSampleProfError(sampleprof_error::truncated_name_table); return *Idx; } -ErrorOr SampleProfileReaderRawBinary::readStringFromTable() { +Expected SampleProfileReaderRawBinary::readStringFromTable() { auto Idx = readStringIndex(NameTable); - if (std::error_code EC = Idx.getError()) - return EC; + if (!Idx) + return Idx.takeError(); return NameTable[*Idx]; } -ErrorOr SampleProfileReaderCompactBinary::readStringFromTable() { +Expected SampleProfileReaderCompactBinary::readStringFromTable() { auto Idx = readStringIndex(NameTable); - if (std::error_code EC = Idx.getError()) - return EC; + if (!Idx) + return Idx.takeError(); return StringRef(NameTable[*Idx]); } -std::error_code -SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) { +Error SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) { auto NumSamples = readNumber(); - if (std::error_code EC = NumSamples.getError()) - return EC; + if (!NumSamples) + return NumSamples.takeError(); FProfile.addTotalSamples(*NumSamples); // Read the samples in the body. auto NumRecords = readNumber(); - if (std::error_code EC = NumRecords.getError()) - return EC; + if (!NumRecords) + return NumRecords.takeError(); for (uint32_t I = 0; I < *NumRecords; ++I) { auto LineOffset = readNumber(); - if (std::error_code EC = LineOffset.getError()) - return EC; + if (!LineOffset) + return LineOffset.takeError(); - if (!isOffsetLegal(*LineOffset)) { - return std::error_code(); - } + if (!isOffsetLegal(*LineOffset)) + return Error::success(); auto Discriminator = readNumber(); - if (std::error_code EC = Discriminator.getError()) - return EC; + if (!Discriminator) + return Discriminator.takeError(); auto NumSamples = readNumber(); - if (std::error_code EC = NumSamples.getError()) - return EC; + if (!NumSamples) + return NumSamples.takeError(); auto NumCalls = readNumber(); - if (std::error_code EC = NumCalls.getError()) - return EC; + if (!NumCalls) + return NumCalls.takeError(); for (uint32_t J = 0; J < *NumCalls; ++J) { - auto CalledFunction(readStringFromTable()); - if (std::error_code EC = CalledFunction.getError()) - return EC; + auto CalledFunction = readStringFromTable(); + if (!CalledFunction) + return CalledFunction.takeError(); auto CalledFunctionSamples = readNumber(); - if (std::error_code EC = CalledFunctionSamples.getError()) - return EC; + if (!CalledFunctionSamples) + return CalledFunctionSamples.takeError(); FProfile.addCalledTargetSamples(*LineOffset, *Discriminator, *CalledFunction, *CalledFunctionSamples); @@ -412,40 +407,40 @@ // Read all the samples for inlined function calls. auto NumCallsites = readNumber(); - if (std::error_code EC = NumCallsites.getError()) - return EC; + if (!NumCallsites) + return NumCallsites.takeError(); for (uint32_t J = 0; J < *NumCallsites; ++J) { auto LineOffset = readNumber(); - if (std::error_code EC = LineOffset.getError()) - return EC; + if (!LineOffset) + return LineOffset.takeError(); auto Discriminator = readNumber(); - if (std::error_code EC = Discriminator.getError()) - return EC; + if (!Discriminator) + return Discriminator.takeError(); auto FName(readStringFromTable()); - if (std::error_code EC = FName.getError()) - return EC; + if (!FName) + return FName.takeError(); FunctionSamples &CalleeProfile = FProfile.functionSamplesAt( LineLocation(*LineOffset, *Discriminator))[*FName]; CalleeProfile.setName(*FName); - if (std::error_code EC = readProfile(CalleeProfile)) - return EC; + if (Error E = readProfile(CalleeProfile)) + return E; } - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileReaderBinary::readFuncProfile() { +Error SampleProfileReaderBinary::readFuncProfile() { auto NumHeadSamples = readNumber(); - if (std::error_code EC = NumHeadSamples.getError()) - return EC; + if (!NumHeadSamples) + return NumHeadSamples.takeError(); auto FName(readStringFromTable()); - if (std::error_code EC = FName.getError()) - return EC; + if (!FName) + return FName.takeError(); Profiles[*FName] = FunctionSamples(); FunctionSamples &FProfile = Profiles[*FName]; @@ -453,21 +448,21 @@ FProfile.addHeadSamples(*NumHeadSamples); - if (std::error_code EC = readProfile(FProfile)) - return EC; - return sampleprof_error::success; + if (Error E = readProfile(FProfile)) + return E; + return Error::success(); } -std::error_code SampleProfileReaderBinary::read() { +Error SampleProfileReaderBinary::read() { while (!at_eof()) { - if (std::error_code EC = readFuncProfile()) - return EC; + if (Error E = readFuncProfile()) + return E; } - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileReaderCompactBinary::read() { +Error SampleProfileReaderCompactBinary::read() { for (auto Name : FuncsToUse) { auto GUID = std::to_string(MD5Hash(Name)); auto iter = FuncOffsetTable.find(StringRef(GUID)); @@ -476,92 +471,92 @@ const uint8_t *SavedData = Data; Data = reinterpret_cast(Buffer->getBufferStart()) + iter->second; - if (std::error_code EC = readFuncProfile()) - return EC; + if (Error E = readFuncProfile()) + return E; Data = SavedData; } - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileReaderRawBinary::verifySPMagic(uint64_t Magic) { +Error SampleProfileReaderRawBinary::verifySPMagic(uint64_t Magic) { if (Magic == SPMagic()) - return sampleprof_error::success; - return sampleprof_error::bad_magic; + return Error::success(); + return createSampleProfError(sampleprof_error::bad_magic); } -std::error_code -SampleProfileReaderCompactBinary::verifySPMagic(uint64_t Magic) { +Error SampleProfileReaderCompactBinary::verifySPMagic(uint64_t Magic) { if (Magic == SPMagic(SPF_Compact_Binary)) - return sampleprof_error::success; - return sampleprof_error::bad_magic; + return Error::success(); + return createSampleProfError(sampleprof_error::bad_magic); } -std::error_code SampleProfileReaderRawBinary::readNameTable() { +Error SampleProfileReaderRawBinary::readNameTable() { auto Size = readNumber(); - if (std::error_code EC = Size.getError()) - return EC; + if (!Size) + return Size.takeError(); NameTable.reserve(*Size); for (uint32_t I = 0; I < *Size; ++I) { auto Name(readString()); - if (std::error_code EC = Name.getError()) - return EC; + if (!Name) + return Name.takeError(); NameTable.push_back(*Name); } - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileReaderCompactBinary::readNameTable() { +Error SampleProfileReaderCompactBinary::readNameTable() { auto Size = readNumber(); - if (std::error_code EC = Size.getError()) - return EC; + if (!Size) + return Size.takeError(); NameTable.reserve(*Size); for (uint32_t I = 0; I < *Size; ++I) { auto FID = readNumber(); - if (std::error_code EC = FID.getError()) - return EC; + if (!FID) + return FID.takeError(); NameTable.push_back(std::to_string(*FID)); } - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileReaderBinary::readHeader() { +Error SampleProfileReaderBinary::readHeader() { Data = reinterpret_cast(Buffer->getBufferStart()); End = Data + Buffer->getBufferSize(); // Read and check the magic identifier. auto Magic = readNumber(); - if (std::error_code EC = Magic.getError()) - return EC; - else if (std::error_code EC = verifySPMagic(*Magic)) - return EC; + if (!Magic) + return Magic.takeError(); + else if (Error E = verifySPMagic(*Magic)) + return E; // Read the version number. auto Version = readNumber(); - if (std::error_code EC = Version.getError()) - return EC; + if (!Version) + return Version.takeError(); else if (*Version != SPVersion()) - return sampleprof_error::unsupported_version; + return createSampleProfError(sampleprof_error::unsupported_version); - if (std::error_code EC = readSummary()) - return EC; + if (Error E = readSummary()) + return E; - if (std::error_code EC = readNameTable()) - return EC; - return sampleprof_error::success; + if (Error E = readNameTable()) + return E; + return Error::success(); } -std::error_code SampleProfileReaderCompactBinary::readHeader() { - SampleProfileReaderBinary::readHeader(); - if (std::error_code EC = readFuncOffsetTable()) - return EC; - return sampleprof_error::success; +Error SampleProfileReaderCompactBinary::readHeader() { + if (Error E = SampleProfileReaderBinary::readHeader()) + return E; + if (Error E = readFuncOffsetTable()) + return E; + return Error::success(); } -std::error_code SampleProfileReaderCompactBinary::readFuncOffsetTable() { +Error SampleProfileReaderCompactBinary::readFuncOffsetTable() { auto TableOffset = readUnencodedNumber(); - if (std::error_code EC = TableOffset.getError()) - return EC; + if (!TableOffset) + return TableOffset.takeError(); const uint8_t *SavedData = Data; const uint8_t *TableStart = @@ -570,24 +565,24 @@ Data = TableStart; auto Size = readNumber(); - if (std::error_code EC = Size.getError()) - return EC; + if (!Size) + return Size.takeError(); FuncOffsetTable.reserve(*Size); for (uint32_t I = 0; I < *Size; ++I) { auto FName(readStringFromTable()); - if (std::error_code EC = FName.getError()) - return EC; + if (!FName) + return FName.takeError(); auto Offset = readNumber(); - if (std::error_code EC = Offset.getError()) - return EC; + if (!Offset) + return Offset.takeError(); FuncOffsetTable[*FName] = *Offset; } End = TableStart; Data = SavedData; - return sampleprof_error::success; + return Error::success(); } void SampleProfileReaderCompactBinary::collectFuncsToUse(const Module &M) { @@ -598,60 +593,58 @@ } } -std::error_code SampleProfileReaderBinary::readSummaryEntry( +Error SampleProfileReaderBinary::readSummaryEntry( std::vector &Entries) { auto Cutoff = readNumber(); - if (std::error_code EC = Cutoff.getError()) - return EC; + if (!Cutoff) + return Cutoff.takeError(); auto MinBlockCount = readNumber(); - if (std::error_code EC = MinBlockCount.getError()) - return EC; + if (!MinBlockCount) + return MinBlockCount.takeError(); auto NumBlocks = readNumber(); - if (std::error_code EC = NumBlocks.getError()) - return EC; + if (!NumBlocks) + return NumBlocks.takeError(); Entries.emplace_back(*Cutoff, *MinBlockCount, *NumBlocks); - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileReaderBinary::readSummary() { +Error SampleProfileReaderBinary::readSummary() { auto TotalCount = readNumber(); - if (std::error_code EC = TotalCount.getError()) - return EC; + if (!TotalCount) + return TotalCount.takeError(); auto MaxBlockCount = readNumber(); - if (std::error_code EC = MaxBlockCount.getError()) - return EC; + if (!MaxBlockCount) + return MaxBlockCount.takeError(); auto MaxFunctionCount = readNumber(); - if (std::error_code EC = MaxFunctionCount.getError()) - return EC; + if (!MaxFunctionCount) + return MaxFunctionCount.takeError(); auto NumBlocks = readNumber(); - if (std::error_code EC = NumBlocks.getError()) - return EC; + if (!NumBlocks) + return NumBlocks.takeError(); auto NumFunctions = readNumber(); - if (std::error_code EC = NumFunctions.getError()) - return EC; + if (!NumFunctions) + return NumFunctions.takeError(); auto NumSummaryEntries = readNumber(); - if (std::error_code EC = NumSummaryEntries.getError()) - return EC; + if (!NumSummaryEntries) + return NumSummaryEntries.takeError(); std::vector Entries; - for (unsigned i = 0; i < *NumSummaryEntries; i++) { - std::error_code EC = readSummaryEntry(Entries); - if (EC != sampleprof_error::success) - return EC; - } + for (unsigned i = 0; i < *NumSummaryEntries; ++i) + if (Error E = readSummaryEntry(Entries)) + return E; Summary = llvm::make_unique( ProfileSummary::PSK_Sample, Entries, *TotalCount, *MaxBlockCount, 0, *MaxFunctionCount, *NumBlocks, *NumFunctions); - return sampleprof_error::success; + return Error::success(); } bool SampleProfileReaderRawBinary::hasFormat(const MemoryBuffer &Buffer) { @@ -668,14 +661,14 @@ return Magic == SPMagic(SPF_Compact_Binary); } -std::error_code SampleProfileReaderGCC::skipNextWord() { +Error SampleProfileReaderGCC::skipNextWord() { uint32_t dummy; if (!GcovBuffer.readInt(dummy)) - return sampleprof_error::truncated; - return sampleprof_error::success; + return createSampleProfError(sampleprof_error::truncated); + return Error::success(); } -template ErrorOr SampleProfileReaderGCC::readNumber() { +template Expected SampleProfileReaderGCC::readNumber() { if (sizeof(T) <= sizeof(uint32_t)) { uint32_t Val; if (GcovBuffer.readInt(Val) && Val <= std::numeric_limits::max()) @@ -686,108 +679,108 @@ return static_cast(Val); } - std::error_code EC = sampleprof_error::malformed; - reportError(0, EC.message()); - return EC; + Error E = createSampleProfError(sampleprof_error::malformed); + reportError(0, E); + return std::move(E); } -ErrorOr SampleProfileReaderGCC::readString() { +Expected SampleProfileReaderGCC::readString() { StringRef Str; if (!GcovBuffer.readString(Str)) - return sampleprof_error::truncated; + return createSampleProfError(sampleprof_error::truncated); return Str; } -std::error_code SampleProfileReaderGCC::readHeader() { +Error SampleProfileReaderGCC::readHeader() { // Read the magic identifier. if (!GcovBuffer.readGCDAFormat()) - return sampleprof_error::unrecognized_format; + return createSampleProfError(sampleprof_error::unrecognized_format); // Read the version number. Note - the GCC reader does not validate this // version, but the profile creator generates v704. GCOV::GCOVVersion version; if (!GcovBuffer.readGCOVVersion(version)) - return sampleprof_error::unrecognized_format; + return createSampleProfError(sampleprof_error::unrecognized_format); if (version != GCOV::V704) - return sampleprof_error::unsupported_version; + return createSampleProfError(sampleprof_error::unsupported_version); // Skip the empty integer. - if (std::error_code EC = skipNextWord()) - return EC; + if (Error E = skipNextWord()) + return E; - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileReaderGCC::readSectionTag(uint32_t Expected) { +Error SampleProfileReaderGCC::readSectionTag(uint32_t Expected) { uint32_t Tag; if (!GcovBuffer.readInt(Tag)) - return sampleprof_error::truncated; + return createSampleProfError(sampleprof_error::truncated); if (Tag != Expected) - return sampleprof_error::malformed; + return createSampleProfError(sampleprof_error::malformed); - if (std::error_code EC = skipNextWord()) - return EC; + if (Error E = skipNextWord()) + return E; - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileReaderGCC::readNameTable() { - if (std::error_code EC = readSectionTag(GCOVTagAFDOFileNames)) - return EC; +Error SampleProfileReaderGCC::readNameTable() { + if (Error E = readSectionTag(GCOVTagAFDOFileNames)) + return E; uint32_t Size; if (!GcovBuffer.readInt(Size)) - return sampleprof_error::truncated; + return createSampleProfError(sampleprof_error::truncated); for (uint32_t I = 0; I < Size; ++I) { StringRef Str; if (!GcovBuffer.readString(Str)) - return sampleprof_error::truncated; + return createSampleProfError(sampleprof_error::truncated); Names.push_back(Str); } - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileReaderGCC::readFunctionProfiles() { - if (std::error_code EC = readSectionTag(GCOVTagAFDOFunction)) - return EC; +Error SampleProfileReaderGCC::readFunctionProfiles() { + if (Error E = readSectionTag(GCOVTagAFDOFunction)) + return E; uint32_t NumFunctions; if (!GcovBuffer.readInt(NumFunctions)) - return sampleprof_error::truncated; + return createSampleProfError(sampleprof_error::truncated); InlineCallStack Stack; for (uint32_t I = 0; I < NumFunctions; ++I) - if (std::error_code EC = readOneFunctionProfile(Stack, true, 0)) - return EC; + if (Error E = readOneFunctionProfile(Stack, true, 0)) + return E; computeSummary(); - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileReaderGCC::readOneFunctionProfile( +Error SampleProfileReaderGCC::readOneFunctionProfile( const InlineCallStack &InlineStack, bool Update, uint32_t Offset) { uint64_t HeadCount = 0; if (InlineStack.size() == 0) if (!GcovBuffer.readInt64(HeadCount)) - return sampleprof_error::truncated; + return createSampleProfError(sampleprof_error::truncated); uint32_t NameIdx; if (!GcovBuffer.readInt(NameIdx)) - return sampleprof_error::truncated; + return createSampleProfError(sampleprof_error::truncated); StringRef Name(Names[NameIdx]); uint32_t NumPosCounts; if (!GcovBuffer.readInt(NumPosCounts)) - return sampleprof_error::truncated; + return createSampleProfError(sampleprof_error::truncated); uint32_t NumCallsites; if (!GcovBuffer.readInt(NumCallsites)) - return sampleprof_error::truncated; + return createSampleProfError(sampleprof_error::truncated); FunctionSamples *FProfile = nullptr; if (InlineStack.size() == 0) { @@ -816,15 +809,15 @@ for (uint32_t I = 0; I < NumPosCounts; ++I) { uint32_t Offset; if (!GcovBuffer.readInt(Offset)) - return sampleprof_error::truncated; + return createSampleProfError(sampleprof_error::truncated); uint32_t NumTargets; if (!GcovBuffer.readInt(NumTargets)) - return sampleprof_error::truncated; + return createSampleProfError(sampleprof_error::truncated); uint64_t Count; if (!GcovBuffer.readInt64(Count)) - return sampleprof_error::truncated; + return createSampleProfError(sampleprof_error::truncated); // The line location is encoded in the offset as: // high 16 bits: line offset to the start of the function. @@ -851,19 +844,19 @@ for (uint32_t J = 0; J < NumTargets; J++) { uint32_t HistVal; if (!GcovBuffer.readInt(HistVal)) - return sampleprof_error::truncated; + return createSampleProfError(sampleprof_error::truncated); if (HistVal != HIST_TYPE_INDIR_CALL_TOPN) - return sampleprof_error::malformed; + return createSampleProfError(sampleprof_error::malformed); uint64_t TargetIdx; if (!GcovBuffer.readInt64(TargetIdx)) - return sampleprof_error::truncated; + return createSampleProfError(sampleprof_error::truncated); StringRef TargetName(Names[TargetIdx]); uint64_t TargetCount; if (!GcovBuffer.readInt64(TargetCount)) - return sampleprof_error::truncated; + return createSampleProfError(sampleprof_error::truncated); if (Update) FProfile->addCalledTargetSamples(LineOffset, Discriminator, @@ -879,31 +872,31 @@ // low 16 bits: discriminator. uint32_t Offset; if (!GcovBuffer.readInt(Offset)) - return sampleprof_error::truncated; + return createSampleProfError(sampleprof_error::truncated); InlineCallStack NewStack; NewStack.push_back(FProfile); NewStack.insert(NewStack.end(), InlineStack.begin(), InlineStack.end()); - if (std::error_code EC = readOneFunctionProfile(NewStack, Update, Offset)) - return EC; + if (Error E = readOneFunctionProfile(NewStack, Update, Offset)) + return E; } - return sampleprof_error::success; + return Error::success(); } /// Read a GCC AutoFDO profile. /// /// This format is generated by the Linux Perf conversion tool at /// https://github.com/google/autofdo. -std::error_code SampleProfileReaderGCC::read() { +Error SampleProfileReaderGCC::read() { // Read the string table. - if (std::error_code EC = readNameTable()) - return EC; + if (Error E = readNameTable()) + return E; // Read the source profile. - if (std::error_code EC = readFunctionProfiles()) - return EC; + if (Error E = readFunctionProfiles()) + return E; - return sampleprof_error::success; + return Error::success(); } bool SampleProfileReaderGCC::hasFormat(const MemoryBuffer &Buffer) { @@ -911,7 +904,7 @@ return Magic == "adcg*704"; } -std::error_code SampleProfileReaderItaniumRemapper::read() { +Error SampleProfileReaderItaniumRemapper::read() { // If the underlying data is in compact format, we can't remap it because // we don't know what the original function names were. if (getFormat() == SPF_Compact_Binary) { @@ -920,7 +913,7 @@ "Profile data remapping cannot be applied to profile data " "in compact format (original mangled names are not available).", DS_Warning)); - return sampleprof_error::success; + return Error::success(); } if (Error E = Remappings.read(*Buffer)) { @@ -928,14 +921,14 @@ std::move(E), [&](const SymbolRemappingParseError &ParseError) { reportError(ParseError.getLineNum(), ParseError.getMessage()); }); - return sampleprof_error::malformed; + return createSampleProfError(sampleprof_error::malformed); } for (auto &Sample : getProfiles()) if (auto Key = Remappings.insert(Sample.first())) SampleMap.insert({Key, &Sample.second}); - return sampleprof_error::success; + return Error::success(); } FunctionSamples * @@ -948,16 +941,16 @@ /// Prepare a memory buffer for the contents of \p Filename. /// /// \returns an error code indicating the status of the buffer. -static ErrorOr> +static Expected> setupMemoryBuffer(const Twine &Filename) { auto BufferOrErr = MemoryBuffer::getFileOrSTDIN(Filename); if (std::error_code EC = BufferOrErr.getError()) - return EC; + return errorCodeToError(EC); auto Buffer = std::move(BufferOrErr.get()); // Sanity check the file. if (uint64_t(Buffer->getBufferSize()) > std::numeric_limits::max()) - return sampleprof_error::too_large; + return createSampleProfError(sampleprof_error::too_large); return std::move(Buffer); } @@ -969,11 +962,11 @@ /// \param C The LLVM context to use to emit diagnostics. /// /// \returns an error code indicating the status of the created reader. -ErrorOr> +Expected> SampleProfileReader::create(const Twine &Filename, LLVMContext &C) { auto BufferOrError = setupMemoryBuffer(Filename); - if (std::error_code EC = BufferOrError.getError()) - return EC; + if (!BufferOrError) + return BufferOrError.takeError(); return create(BufferOrError.get(), C); } @@ -986,14 +979,14 @@ /// /// \param Underlying The underlying profile data reader to remap. /// -/// \returns an error code indicating the status of the created reader. -ErrorOr> +/// \returns an Expected indicating the status of the created reader. +Expected> SampleProfileReaderItaniumRemapper::create( const Twine &Filename, LLVMContext &C, std::unique_ptr Underlying) { auto BufferOrError = setupMemoryBuffer(Filename); - if (std::error_code EC = BufferOrError.getError()) - return EC; + if (!BufferOrError) + return BufferOrError.takeError(); return llvm::make_unique( std::move(BufferOrError.get()), C, std::move(Underlying)); } @@ -1004,8 +997,8 @@ /// /// \param C The LLVM context to use to emit diagnostics. /// -/// \returns an error code indicating the status of the created reader. -ErrorOr> +/// \returns an Expected indicating the status of the created reader. +Expected> SampleProfileReader::create(std::unique_ptr &B, LLVMContext &C) { std::unique_ptr Reader; if (SampleProfileReaderRawBinary::hasFormat(*B)) @@ -1017,11 +1010,11 @@ else if (SampleProfileReaderText::hasFormat(*B)) Reader.reset(new SampleProfileReaderText(std::move(B), C)); else - return sampleprof_error::unrecognized_format; + return createSampleProfError(sampleprof_error::unrecognized_format); FunctionSamples::Format = Reader->getFormat(); - if (std::error_code EC = Reader->readHeader()) - return EC; + if (Error E = Reader->readHeader()) + return std::move(E); return std::move(Reader); } Index: lib/ProfileData/SampleProfWriter.cpp =================================================================== --- lib/ProfileData/SampleProfWriter.cpp +++ lib/ProfileData/SampleProfWriter.cpp @@ -39,10 +39,9 @@ using namespace llvm; using namespace sampleprof; -std::error_code -SampleProfileWriter::write(const StringMap &ProfileMap) { - if (std::error_code EC = writeHeader(ProfileMap)) - return EC; +Error SampleProfileWriter::write(const StringMap &ProfileMap) { + if (Error E = writeHeader(ProfileMap)) + return E; // Sort the ProfileMap by total samples. typedef std::pair NameFunctionSamples; @@ -59,19 +58,19 @@ }); for (const auto &I : V) { - if (std::error_code EC = write(*I.second)) - return EC; + if (Error E = write(*I.second)) + return E; } - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileWriterCompactBinary::write( +Error SampleProfileWriterCompactBinary::write( const StringMap &ProfileMap) { - if (std::error_code EC = SampleProfileWriter::write(ProfileMap)) - return EC; - if (std::error_code EC = writeFuncOffsetTable()) - return EC; - return sampleprof_error::success; + if (Error E = SampleProfileWriter::write(ProfileMap)) + return E; + if (Error E = writeFuncOffsetTable()) + return E; + return Error::success(); } /// Write samples to a text file. @@ -82,7 +81,7 @@ /// /// The format used here is more structured and deliberate because /// it needs to be parsed by the SampleProfileReaderText class. -std::error_code SampleProfileWriterText::write(const FunctionSamples &S) { +Error SampleProfileWriterText::write(const FunctionSamples &S) { auto &OS = *OutputStream; OS << S.getName() << ":" << S.getTotalSamples(); if (Indent == 0) @@ -118,20 +117,20 @@ OS << Loc.LineOffset << ": "; else OS << Loc.LineOffset << "." << Loc.Discriminator << ": "; - if (std::error_code EC = write(CalleeSamples)) - return EC; + if (Error E = write(CalleeSamples)) + return E; } Indent -= 1; - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileWriterBinary::writeNameIdx(StringRef FName) { +Error SampleProfileWriterBinary::writeNameIdx(StringRef FName) { const auto &ret = NameTable.find(FName); if (ret == NameTable.end()) - return sampleprof_error::truncated_name_table; + return createSampleProfError(sampleprof_error::truncated_name_table); encodeULEB128(ret->second, *OutputStream); - return sampleprof_error::success; + return Error::success(); } void SampleProfileWriterBinary::addName(StringRef FName) { @@ -164,7 +163,7 @@ NameTable[N] = i++; } -std::error_code SampleProfileWriterRawBinary::writeNameTable() { +Error SampleProfileWriterRawBinary::writeNameTable() { auto &OS = *OutputStream; std::set V; stablizeNameTable(V); @@ -175,34 +174,35 @@ OS << N; encodeULEB128(0, OS); } - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileWriterCompactBinary::writeFuncOffsetTable() { +Error SampleProfileWriterCompactBinary::writeFuncOffsetTable() { auto &OS = *OutputStream; // Fill the slot remembered by TableOffset with the offset of FuncOffsetTable. auto &OFS = static_cast(OS); uint64_t FuncOffsetTableStart = OS.tell(); if (OFS.seek(TableOffset) == (uint64_t)-1) - return sampleprof_error::ostream_seek_unsupported; + return createSampleProfError(sampleprof_error::ostream_seek_unsupported); support::endian::Writer Writer(*OutputStream, support::little); Writer.write(FuncOffsetTableStart); if (OFS.seek(FuncOffsetTableStart) == (uint64_t)-1) - return sampleprof_error::ostream_seek_unsupported; + return createSampleProfError(sampleprof_error::ostream_seek_unsupported); // Write out the table size. encodeULEB128(FuncOffsetTable.size(), OS); // Write out FuncOffsetTable. for (auto entry : FuncOffsetTable) { - writeNameIdx(entry.first); + if (Error E = writeNameIdx(entry.first)) + return E; encodeULEB128(entry.second, OS); } - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileWriterCompactBinary::writeNameTable() { +Error SampleProfileWriterCompactBinary::writeNameTable() { auto &OS = *OutputStream; std::set V; stablizeNameTable(V); @@ -212,32 +212,32 @@ for (auto N : V) { encodeULEB128(MD5Hash(N), OS); } - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileWriterRawBinary::writeMagicIdent() { +Error SampleProfileWriterRawBinary::writeMagicIdent() { auto &OS = *OutputStream; // Write file magic identifier. encodeULEB128(SPMagic(), OS); encodeULEB128(SPVersion(), OS); - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileWriterCompactBinary::writeMagicIdent() { +Error SampleProfileWriterCompactBinary::writeMagicIdent() { auto &OS = *OutputStream; // Write file magic identifier. encodeULEB128(SPMagic(SPF_Compact_Binary), OS); encodeULEB128(SPVersion(), OS); - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileWriterBinary::writeHeader( +Error SampleProfileWriterBinary::writeHeader( const StringMap &ProfileMap) { - writeMagicIdent(); + (void)writeMagicIdent(); computeSummary(ProfileMap); - if (auto EC = writeSummary()) - return EC; + if (Error E = writeSummary()) + return E; // Generate the name table for all the functions referenced in the profile. for (const auto &I : ProfileMap) { @@ -245,24 +245,24 @@ addNames(I.second); } - writeNameTable(); - return sampleprof_error::success; + (void)writeNameTable(); + return Error::success(); } -std::error_code SampleProfileWriterCompactBinary::writeHeader( +Error SampleProfileWriterCompactBinary::writeHeader( const StringMap &ProfileMap) { support::endian::Writer Writer(*OutputStream, support::little); - if (auto EC = SampleProfileWriterBinary::writeHeader(ProfileMap)) - return EC; + if (Error E = SampleProfileWriterBinary::writeHeader(ProfileMap)) + return E; // Reserve a slot for the offset of function offset table. The slot will // be populated with the offset of FuncOffsetTable later. TableOffset = OutputStream->tell(); Writer.write(static_cast(-2)); - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileWriterBinary::writeSummary() { +Error SampleProfileWriterBinary::writeSummary() { auto &OS = *OutputStream; encodeULEB128(Summary->getTotalCount(), OS); encodeULEB128(Summary->getMaxCount(), OS); @@ -276,13 +276,14 @@ encodeULEB128(Entry.MinCount, OS); encodeULEB128(Entry.NumCounts, OS); } - return sampleprof_error::success; + return Error::success(); } -std::error_code SampleProfileWriterBinary::writeBody(const FunctionSamples &S) { + +Error SampleProfileWriterBinary::writeBody(const FunctionSamples &S) { auto &OS = *OutputStream; - if (std::error_code EC = writeNameIdx(S.getName())) - return EC; + if (Error E = writeNameIdx(S.getName())) + return E; encodeULEB128(S.getTotalSamples(), OS); @@ -298,8 +299,8 @@ for (const auto &J : Sample.getCallTargets()) { StringRef Callee = J.first(); uint64_t CalleeSamples = J.second; - if (std::error_code EC = writeNameIdx(Callee)) - return EC; + if (Error E = writeNameIdx(Callee)) + return E; encodeULEB128(CalleeSamples, OS); } } @@ -315,23 +316,22 @@ const FunctionSamples &CalleeSamples = FS.second; encodeULEB128(Loc.LineOffset, OS); encodeULEB128(Loc.Discriminator, OS); - if (std::error_code EC = writeBody(CalleeSamples)) - return EC; + if (Error E = writeBody(CalleeSamples)) + return E; } - return sampleprof_error::success; + return Error::success(); } /// Write samples of a top-level function to a binary file. /// /// \returns true if the samples were written successfully, false otherwise. -std::error_code SampleProfileWriterBinary::write(const FunctionSamples &S) { +Error SampleProfileWriterBinary::write(const FunctionSamples &S) { encodeULEB128(S.getHeadSamples(), *OutputStream); return writeBody(S); } -std::error_code -SampleProfileWriterCompactBinary::write(const FunctionSamples &S) { +Error SampleProfileWriterCompactBinary::write(const FunctionSamples &S) { uint64_t Offset = OutputStream->tell(); StringRef Name = S.getName(); FuncOffsetTable[Name] = Offset; @@ -346,7 +346,7 @@ /// \param Format Encoding format for the profile file. /// /// \returns an error code indicating the status of the created writer. -ErrorOr> +Expected> SampleProfileWriter::create(StringRef Filename, SampleProfileFormat Format) { std::error_code EC; std::unique_ptr OS; @@ -355,7 +355,7 @@ else OS.reset(new raw_fd_ostream(Filename, EC, sys::fs::F_Text)); if (EC) - return EC; + return errorCodeToError(EC); return create(OS, Format); } @@ -366,11 +366,10 @@ /// /// \param Format Encoding format for the profile file. /// -/// \returns an error code indicating the status of the created writer. -ErrorOr> +/// \returns an Expected indicating the status of the created writer. +Expected> SampleProfileWriter::create(std::unique_ptr &OS, SampleProfileFormat Format) { - std::error_code EC; std::unique_ptr Writer; if (Format == SPF_Binary) @@ -380,12 +379,9 @@ else if (Format == SPF_Text) Writer.reset(new SampleProfileWriterText(OS)); else if (Format == SPF_GCC) - EC = sampleprof_error::unsupported_writing_format; + return createSampleProfError(sampleprof_error::unsupported_writing_format); else - EC = sampleprof_error::unrecognized_format; - - if (EC) - return EC; + return createSampleProfError(sampleprof_error::unrecognized_format); return std::move(Writer); } Index: lib/Target/X86/X86InsertPrefetch.cpp =================================================================== --- lib/Target/X86/X86InsertPrefetch.cpp +++ lib/Target/X86/X86InsertPrefetch.cpp @@ -158,16 +158,21 @@ return false; LLVMContext &Ctx = M.getContext(); - ErrorOr> ReaderOrErr = + Expected> ReaderOrErr = SampleProfileReader::create(Filename, Ctx); - if (std::error_code EC = ReaderOrErr.getError()) { - std::string Msg = "Could not open profile: " + EC.message(); + if (!ReaderOrErr) { + std::string Msg = + "Could not open profile: " + toString(ReaderOrErr.takeError()); Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, Msg, DiagnosticSeverity::DS_Warning)); return false; } Reader = std::move(ReaderOrErr.get()); - Reader->read(); + if (Error E = Reader->read()) { + Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, toString(std::move(E)), + DiagnosticSeverity::DS_Warning)); + return false; + } return true; } Index: lib/Transforms/IPO/SampleProfile.cpp =================================================================== --- lib/Transforms/IPO/SampleProfile.cpp +++ lib/Transforms/IPO/SampleProfile.cpp @@ -1557,14 +1557,15 @@ bool SampleProfileLoader::doInitialization(Module &M) { auto &Ctx = M.getContext(); auto ReaderOrErr = SampleProfileReader::create(Filename, Ctx); - if (std::error_code EC = ReaderOrErr.getError()) { - std::string Msg = "Could not open profile: " + EC.message(); + if (!ReaderOrErr) { + std::string Msg = + "Could not open profile: " + toString(ReaderOrErr.takeError()); Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, Msg)); return false; } Reader = std::move(ReaderOrErr.get()); Reader->collectFuncsToUse(M); - ProfileIsValid = (Reader->read() == sampleprof_error::success); + ProfileIsValid = !Reader->read(); if (!RemappingFilename.empty()) { // Apply profile remappings to the loaded profile data if requested. @@ -1572,13 +1573,14 @@ // C++ ABI's name mangling scheme. ReaderOrErr = SampleProfileReaderItaniumRemapper::create( RemappingFilename, Ctx, std::move(Reader)); - if (std::error_code EC = ReaderOrErr.getError()) { - std::string Msg = "Could not open profile remapping file: " + EC.message(); + if (!ReaderOrErr) { + std::string Msg = "Could not open profile remapping file: " + + toString(ReaderOrErr.takeError()); Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, Msg)); return false; } Reader = std::move(ReaderOrErr.get()); - ProfileIsValid = (Reader->read() == sampleprof_error::success); + ProfileIsValid = !Reader->read(); } return true; } Index: tools/llvm-profdata/llvm-profdata.cpp =================================================================== --- tools/llvm-profdata/llvm-profdata.cpp +++ tools/llvm-profdata/llvm-profdata.cpp @@ -409,8 +409,8 @@ using namespace sampleprof; auto WriterOrErr = SampleProfileWriter::create(OutputFilename, FormatMap[OutputFormat]); - if (std::error_code EC = WriterOrErr.getError()) - exitWithErrorCode(EC, OutputFilename); + if (!WriterOrErr) + exitWithError(WriterOrErr.takeError(), OutputFilename); auto Writer = std::move(WriterOrErr.get()); StringMap ProfileMap; @@ -418,8 +418,8 @@ LLVMContext Context; for (const auto &Input : Inputs) { auto ReaderOrErr = SampleProfileReader::create(Input.Filename, Context); - if (std::error_code EC = ReaderOrErr.getError()) - exitWithErrorCode(EC, Input.Filename); + if (!ReaderOrErr) + exitWithError(ReaderOrErr.takeError(), Input.Filename); // We need to keep the readers around until after all the files are // read so that we do not lose the function names stored in each @@ -427,8 +427,8 @@ // merged profile map. Readers.push_back(std::move(ReaderOrErr.get())); const auto Reader = Readers.back().get(); - if (std::error_code EC = Reader->read()) - exitWithErrorCode(EC, Input.Filename); + if (Error E = Reader->read()) + exitWithError(std::move(E), Input.Filename); StringMap &Profiles = Reader->getProfiles(); for (StringMap::iterator I = Profiles.begin(), @@ -441,13 +441,13 @@ FunctionSamples &Samples = Remapper ? Remapped : I->second; StringRef FName = Samples.getName(); MergeResult(Result, ProfileMap[FName].merge(Samples, Input.Weight)); - if (Result != sampleprof_error::success) { - std::error_code EC = make_error_code(Result); - handleMergeWriterError(errorCodeToError(EC), Input.Filename, FName); - } + if (Result != sampleprof_error::success) + handleMergeWriterError(createSampleProfError(Result), Input.Filename, + FName); } } - Writer->write(ProfileMap); + if (Error E = Writer->write(ProfileMap)) + exitWithError(std::move(E)); } static WeightedFile parseWeightedFile(const StringRef &WeightedFilename) { @@ -866,12 +866,12 @@ using namespace sampleprof; LLVMContext Context; auto ReaderOrErr = SampleProfileReader::create(Filename, Context); - if (std::error_code EC = ReaderOrErr.getError()) - exitWithErrorCode(EC, Filename); + if (!ReaderOrErr) + exitWithError(ReaderOrErr.takeError(), Filename); auto Reader = std::move(ReaderOrErr.get()); - if (std::error_code EC = Reader->read()) - exitWithErrorCode(EC, Filename); + if (Error E = Reader->read()) + exitWithError(std::move(E), Filename); if (ShowAllFunctions || ShowFunction.empty()) Reader->dump(OS); Index: unittests/ProfileData/SampleProfTest.cpp =================================================================== --- unittests/ProfileData/SampleProfTest.cpp +++ unittests/ProfileData/SampleProfTest.cpp @@ -28,8 +28,21 @@ static ::testing::AssertionResult NoError(std::error_code EC) { if (!EC) return ::testing::AssertionSuccess(); - return ::testing::AssertionFailure() << "error " << EC.value() << ": " - << EC.message(); + return ::testing::AssertionFailure() + << "error " << EC.value() << ": " << EC.message(); +} + +static ::testing::AssertionResult NoError(Error E) { + if (!E) + return ::testing::AssertionSuccess(); + return ::testing::AssertionFailure() << "error " << toString(std::move(E)); +} + +template +static ::testing::AssertionResult NoError(Expected &EC) { + if (EC) + return ::testing::AssertionSuccess(); + return ::testing::AssertionFailure() << "error " << toString(EC.takeError()); } namespace { @@ -46,13 +59,13 @@ std::unique_ptr OS( new raw_fd_ostream(Profile, EC, sys::fs::F_None)); auto WriterOrErr = SampleProfileWriter::create(OS, Format); - ASSERT_TRUE(NoError(WriterOrErr.getError())); + ASSERT_TRUE(NoError(WriterOrErr)); Writer = std::move(WriterOrErr.get()); } void readProfile(const Module &M, StringRef Profile) { auto ReaderOrErr = SampleProfileReader::create(Profile, Context); - ASSERT_TRUE(NoError(ReaderOrErr.getError())); + ASSERT_TRUE(NoError(ReaderOrErr)); Reader = std::move(ReaderOrErr.get()); Reader->collectFuncsToUse(M); } @@ -96,16 +109,13 @@ Profiles[FooName] = std::move(FooSamples); Profiles[BarName] = std::move(BarSamples); - std::error_code EC; - EC = Writer->write(Profiles); - ASSERT_TRUE(NoError(EC)); + ASSERT_TRUE(NoError(Writer->write(Profiles))); Writer->getOutputStream().flush(); readProfile(M, Profile); - EC = Reader->read(); - ASSERT_TRUE(NoError(EC)); + ASSERT_TRUE(NoError(Reader->read())); if (Remap) { auto MemBuffer = llvm::MemoryBuffer::getMemBuffer(R"( @@ -119,8 +129,7 @@ FooName = "_Z4fauxi"; BarName = "_Z3barl"; - EC = Reader->read(); - ASSERT_TRUE(NoError(EC)); + ASSERT_TRUE(NoError(Reader->read())); } ASSERT_EQ(2u, Reader->getProfiles().size()); @@ -254,14 +263,12 @@ // write profile createWriter(Format, ProfileFile); - EC = Writer->write(ProfMap); - ASSERT_TRUE(NoError(EC)); + ASSERT_TRUE(NoError(Writer->write(ProfMap))); Writer->getOutputStream().flush(); // read profile readProfile(M, ProfileFile); - EC = Reader->read(); - ASSERT_TRUE(NoError(EC)); + ASSERT_TRUE(NoError(Reader->read())); for (auto I = Expected.begin(); I != Expected.end(); ++I) { uint64_t Esamples = uint64_t(-1);