[PATCH] Use ErrorOr for the ::create factory on instrumented and sample profilers.
Justin Bogner
mail at justinbogner.com
Sun Nov 2 16:52:34 PST 2014
Diego Novillo <dnovillo at google.com> writes:
> Hi bogner,
>
> As discussed in
> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20141027/242445.html,the creation of reader and writer instances is better done using
> ErrorOr. There are no functional changes, but several callers needed to
> be adjusted.
Thanks for doing this! LGTM.
> http://reviews.llvm.org/D6076
>
> Files:
> include/llvm/ProfileData/InstrProfReader.h
> include/llvm/ProfileData/SampleProfReader.h
> include/llvm/ProfileData/SampleProfWriter.h
> lib/ProfileData/InstrProfReader.cpp
> lib/ProfileData/SampleProfReader.cpp
> lib/ProfileData/SampleProfWriter.cpp
> lib/Transforms/Scalar/SampleProfile.cpp
> tools/llvm-profdata/llvm-profdata.cpp
>
> Index: include/llvm/ProfileData/InstrProfReader.h
> ===================================================================
> --- include/llvm/ProfileData/InstrProfReader.h
> +++ include/llvm/ProfileData/InstrProfReader.h
> @@ -18,6 +18,7 @@
> #include "llvm/ADT/ArrayRef.h"
> #include "llvm/ADT/StringExtras.h"
> #include "llvm/ProfileData/InstrProf.h"
> +#include "llvm/Support/ErrorOr.h"
> #include "llvm/Support/LineIterator.h"
> #include "llvm/Support/MemoryBuffer.h"
> #include "llvm/Support/EndianStream.h"
> @@ -94,8 +95,7 @@
>
> /// Factory method to create an appropriately typed reader for the given
> /// instrprof file.
> - static std::error_code create(std::string Path,
> - std::unique_ptr<InstrProfReader> &Result);
> + static ErrorOr<std::unique_ptr<InstrProfReader>> create(std::string Path);
> };
>
> /// Reader for the simple text based instrprof format.
> Index: include/llvm/ProfileData/SampleProfReader.h
> ===================================================================
> --- include/llvm/ProfileData/SampleProfReader.h
> +++ include/llvm/ProfileData/SampleProfReader.h
> @@ -92,9 +92,8 @@
> }
>
> /// \brief Create a sample profile reader appropriate to the file format.
> - static std::error_code create(StringRef Filename,
> - std::unique_ptr<SampleProfileReader> &Reader,
> - LLVMContext &C);
> + static ErrorOr<std::unique_ptr<SampleProfileReader>>
> + create(StringRef Filename, LLVMContext &C);
>
> protected:
> /// \brief Map every function to its associated profile.
> Index: include/llvm/ProfileData/SampleProfWriter.h
> ===================================================================
> --- include/llvm/ProfileData/SampleProfWriter.h
> +++ include/llvm/ProfileData/SampleProfWriter.h
> @@ -17,6 +17,7 @@
> #include "llvm/IR/Function.h"
> #include "llvm/IR/Module.h"
> #include "llvm/ProfileData/SampleProf.h"
> +#include "llvm/Support/ErrorOr.h"
> #include "llvm/Support/FileSystem.h"
> #include "llvm/Support/raw_ostream.h"
>
> @@ -71,9 +72,8 @@
>
> /// \brief Profile writer factory. Create a new writer based on the value of
> /// \p Format.
> - static std::error_code create(StringRef Filename,
> - std::unique_ptr<SampleProfileWriter> &Result,
> - SampleProfileFormat Format);
> + static ErrorOr<std::unique_ptr<SampleProfileWriter>>
> + create(StringRef Filename, SampleProfileFormat Format);
>
> protected:
> /// \brief Output stream where to emit the profile to.
> Index: lib/ProfileData/InstrProfReader.cpp
> ===================================================================
> --- lib/ProfileData/InstrProfReader.cpp
> +++ lib/ProfileData/InstrProfReader.cpp
> @@ -21,32 +21,34 @@
>
> using namespace llvm;
>
> -static std::error_code
> -setupMemoryBuffer(std::string Path, std::unique_ptr<MemoryBuffer> &Buffer) {
> +static ErrorOr<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;
> - Buffer = std::move(BufferOrErr.get());
> + auto Buffer = std::move(BufferOrErr.get());
>
> // Sanity check the file.
> if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max())
> return instrprof_error::too_large;
> - return instrprof_error::success;
> + return std::move(Buffer);
> }
>
> static std::error_code initializeReader(InstrProfReader &Reader) {
> return Reader.readHeader();
> }
>
> -std::error_code
> -InstrProfReader::create(std::string Path,
> - std::unique_ptr<InstrProfReader> &Result) {
> +ErrorOr<std::unique_ptr<InstrProfReader>>
> +InstrProfReader::create(std::string Path) {
> // Set up the buffer to read.
> - std::unique_ptr<MemoryBuffer> Buffer;
> - if (std::error_code EC = setupMemoryBuffer(Path, Buffer))
> + auto BufferOrError = setupMemoryBuffer(Path);
> + if (std::error_code EC = BufferOrError.getError())
> return EC;
>
> + auto Buffer = std::move(BufferOrError.get());
> + std::unique_ptr<InstrProfReader> Result;
> +
> // Create the reader.
> if (IndexedInstrProfReader::hasFormat(*Buffer))
> Result.reset(new IndexedInstrProfReader(std::move(Buffer)));
> @@ -58,16 +60,20 @@
> Result.reset(new TextInstrProfReader(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);
> }
>
> std::error_code IndexedInstrProfReader::create(
> std::string Path, std::unique_ptr<IndexedInstrProfReader> &Result) {
> // Set up the buffer to read.
> - std::unique_ptr<MemoryBuffer> Buffer;
> - if (std::error_code EC = setupMemoryBuffer(Path, Buffer))
> + auto BufferOrError = setupMemoryBuffer(Path);
> + if (std::error_code EC = BufferOrError.getError())
> return EC;
>
> + auto Buffer = std::move(BufferOrError.get());
> // Create the reader.
> if (!IndexedInstrProfReader::hasFormat(*Buffer))
> return instrprof_error::bad_magic;
> Index: lib/ProfileData/SampleProfReader.cpp
> ===================================================================
> --- lib/ProfileData/SampleProfReader.cpp
> +++ lib/ProfileData/SampleProfReader.cpp
> @@ -356,18 +356,18 @@
> /// \brief Prepare a memory buffer for the contents of \p Filename.
> ///
> /// \returns an error code indicating the status of the buffer.
> -static std::error_code
> -setupMemoryBuffer(std::string Filename, std::unique_ptr<MemoryBuffer> &Buffer) {
> +static ErrorOr<std::unique_ptr<MemoryBuffer>>
> +setupMemoryBuffer(std::string Filename) {
> auto BufferOrErr = MemoryBuffer::getFileOrSTDIN(Filename);
> if (std::error_code EC = BufferOrErr.getError())
> return EC;
> - Buffer = std::move(BufferOrErr.get());
> + auto Buffer = std::move(BufferOrErr.get());
>
> // Sanity check the file.
> if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max())
> return sampleprof_error::too_large;
>
> - return sampleprof_error::success;
> + return std::move(Buffer);
> }
>
> /// \brief Create a sample profile reader based on the format of the input file.
> @@ -379,18 +379,21 @@
> /// \param C The LLVM context to use to emit diagnostics.
> ///
> /// \returns an error code indicating the status of the created reader.
> -std::error_code
> -SampleProfileReader::create(StringRef Filename,
> - std::unique_ptr<SampleProfileReader> &Reader,
> - LLVMContext &C) {
> - std::unique_ptr<MemoryBuffer> Buffer;
> - if (std::error_code EC = setupMemoryBuffer(Filename, Buffer))
> +ErrorOr<std::unique_ptr<SampleProfileReader>>
> +SampleProfileReader::create(StringRef Filename, LLVMContext &C) {
> + auto BufferOrError = setupMemoryBuffer(Filename);
> + if (std::error_code EC = BufferOrError.getError())
> return EC;
>
> + auto Buffer = std::move(BufferOrError.get());
> + std::unique_ptr<SampleProfileReader> Reader;
> if (SampleProfileReaderBinary::hasFormat(*Buffer))
> Reader.reset(new SampleProfileReaderBinary(std::move(Buffer), C));
> else
> Reader.reset(new SampleProfileReaderText(std::move(Buffer), C));
>
> - return Reader->readHeader();
> + if (std::error_code EC = Reader->readHeader())
> + return EC;
> +
> + return std::move(Reader);
> }
> Index: lib/ProfileData/SampleProfWriter.cpp
> ===================================================================
> --- lib/ProfileData/SampleProfWriter.cpp
> +++ lib/ProfileData/SampleProfWriter.cpp
> @@ -107,18 +107,20 @@
> /// \param Format Encoding format for the profile file.
> ///
> /// \returns an error code indicating the status of the created writer.
> -std::error_code
> -SampleProfileWriter::create(StringRef Filename,
> - std::unique_ptr<SampleProfileWriter> &Writer,
> - SampleProfileFormat Format) {
> +ErrorOr<std::unique_ptr<SampleProfileWriter>>
> +SampleProfileWriter::create(StringRef Filename, SampleProfileFormat Format) {
> std::error_code EC;
> + std::unique_ptr<SampleProfileWriter> Writer;
>
> if (Format == SPF_Binary)
> Writer.reset(new SampleProfileWriterBinary(Filename, EC));
> else if (Format == SPF_Text)
> Writer.reset(new SampleProfileWriterText(Filename, EC));
> else
> EC = sampleprof_error::unrecognized_format;
>
> - return EC;
> + if (EC)
> + return EC;
> +
> + return std::move(Writer);
> }
> Index: lib/Transforms/Scalar/SampleProfile.cpp
> ===================================================================
> --- lib/Transforms/Scalar/SampleProfile.cpp
> +++ lib/Transforms/Scalar/SampleProfile.cpp
> @@ -737,12 +737,13 @@
> "Sample Profile loader", false, false)
>
> bool SampleProfileLoader::doInitialization(Module &M) {
> - if (std::error_code EC =
> - SampleProfileReader::create(Filename, Reader, M.getContext())) {
> + auto ReaderOrErr = SampleProfileReader::create(Filename, M.getContext());
> + if (std::error_code EC = ReaderOrErr.getError()) {
> std::string Msg = "Could not open profile: " + EC.message();
> M.getContext().diagnose(DiagnosticInfoSampleProfile(Filename.data(), Msg));
> return false;
> }
> + Reader = std::move(ReaderOrErr.get());
> ProfileIsValid = (Reader->read() == sampleprof_error::success);
> return true;
> }
> Index: tools/llvm-profdata/llvm-profdata.cpp
> ===================================================================
> --- tools/llvm-profdata/llvm-profdata.cpp
> +++ tools/llvm-profdata/llvm-profdata.cpp
> @@ -49,10 +49,11 @@
>
> InstrProfWriter Writer;
> for (const auto &Filename : Inputs) {
> - std::unique_ptr<InstrProfReader> Reader;
> - if (std::error_code ec = InstrProfReader::create(Filename, Reader))
> + auto ReaderOrErr = InstrProfReader::create(Filename);
> + if (std::error_code ec = ReaderOrErr.getError())
> exitWithError(ec.message(), Filename);
>
> + auto Reader = std::move(ReaderOrErr.get());
> for (const auto &I : *Reader)
> if (std::error_code EC =
> Writer.addFunctionCounts(I.Name, I.Hash, I.Counts))
> @@ -66,18 +67,19 @@
> void mergeSampleProfile(cl::list<std::string> Inputs, StringRef OutputFilename,
> sampleprof::SampleProfileFormat OutputFormat) {
> using namespace sampleprof;
> - std::unique_ptr<SampleProfileWriter> Writer;
> - if (std::error_code EC = SampleProfileWriter::create(OutputFilename.data(),
> - Writer, OutputFormat))
> + auto WriterOrErr = SampleProfileWriter::create(OutputFilename, OutputFormat);
> + if (std::error_code EC = WriterOrErr.getError())
> exitWithError(EC.message(), OutputFilename);
>
> + auto Writer = std::move(WriterOrErr.get());
> StringMap<FunctionSamples> ProfileMap;
> for (const auto &Filename : Inputs) {
> - std::unique_ptr<SampleProfileReader> Reader;
> - if (std::error_code EC =
> - SampleProfileReader::create(Filename, Reader, getGlobalContext()))
> + auto ReaderOrErr =
> + SampleProfileReader::create(Filename, getGlobalContext());
> + if (std::error_code EC = ReaderOrErr.getError())
> exitWithError(EC.message(), Filename);
>
> + auto Reader = std::move(ReaderOrErr.get());
> if (std::error_code EC = Reader->read())
> exitWithError(EC.message(), Filename);
>
> @@ -129,10 +131,11 @@
> int showInstrProfile(std::string Filename, bool ShowCounts,
> bool ShowAllFunctions, std::string ShowFunction,
> raw_fd_ostream &OS) {
> - std::unique_ptr<InstrProfReader> Reader;
> - if (std::error_code EC = InstrProfReader::create(Filename, Reader))
> + auto ReaderOrErr = InstrProfReader::create(Filename);
> + if (std::error_code EC = ReaderOrErr.getError())
> exitWithError(EC.message(), Filename);
>
> + auto Reader = std::move(ReaderOrErr.get());
> uint64_t MaxFunctionCount = 0, MaxBlockCount = 0;
> size_t ShownFunctions = 0, TotalFunctions = 0;
> for (const auto &Func : *Reader) {
> @@ -182,11 +185,11 @@
> bool ShowAllFunctions, std::string ShowFunction,
> raw_fd_ostream &OS) {
> using namespace sampleprof;
> - std::unique_ptr<SampleProfileReader> Reader;
> - if (std::error_code EC =
> - SampleProfileReader::create(Filename, Reader, getGlobalContext()))
> + auto ReaderOrErr = SampleProfileReader::create(Filename, getGlobalContext());
> + if (std::error_code EC = ReaderOrErr.getError())
> exitWithError(EC.message(), Filename);
>
> + auto Reader = std::move(ReaderOrErr.get());
> Reader->read();
> if (ShowAllFunctions || ShowFunction.empty())
> Reader->dump(OS);
More information about the llvm-commits
mailing list