Use ErrorOr for the ::create factory on instrumented and sample profilers.
authorDiego Novillo <dnovillo@google.com>
Mon, 3 Nov 2014 00:51:45 +0000 (00:51 +0000)
committerDiego Novillo <dnovillo@google.com>
Mon, 3 Nov 2014 00:51:45 +0000 (00:51 +0000)
Summary:
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.

Reviewers: bogner

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D6076

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221120 91177308-0d34-0410-b5e6-96231b3b80d8

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 4ab774fab456472fe55b6ea6ce0f9dc1a063e36e..38c5310e63d103ead552404aeb525548d6cc7646 100644 (file)
@@ -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 @@ public:
 
   /// 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 e9ceae5d83513d252d6ac90fbff46ca04608e441..c20b815b5d9d16b3296a3367fde0339f07d93a92 100644 (file)
@@ -92,9 +92,8 @@ public:
   }
 
   /// \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 465adb6a20321a119f1b0b5c7c3952d0b3ee7778..302a82d3286122d044cb3eb10ef908e828bde8bc 100644 (file)
@@ -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 @@ public:
 
   /// \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 e333473f6f8d228b9face989d6f0888949852b9d..0160a640fdca016a2d3dc24324fc8aa0d899c1c7 100644 (file)
 
 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 @@ InstrProfReader::create(std::string Path,
     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 a6e4e0ce5022b32c8420cb2a339bc9541b08a0db..b39bfd6e2ecd37d23407df25e40a3fa918fde969 100644 (file)
@@ -356,18 +356,18 @@ bool SampleProfileReaderBinary::hasFormat(const MemoryBuffer &Buffer) {
 /// \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 @@ setupMemoryBuffer(std::string Filename, std::unique_ptr<MemoryBuffer> &Buffer) {
 /// \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 49d6fdbf4f7be05645a237c818e9954a965b310d..85250452bd1b6680876c8aa73f76811fc79d70cc 100644 (file)
@@ -107,11 +107,10 @@ bool SampleProfileWriterBinary::write(StringRef FName,
 /// \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));
@@ -120,5 +119,8 @@ SampleProfileWriter::create(StringRef Filename,
   else
     EC = sampleprof_error::unrecognized_format;
 
-  return EC;
+  if (EC)
+    return EC;
+
+  return std::move(Writer);
 }
index 89f0c27070b0e0297202f1a3567f384df3dbad5d..aa01508d25b53c4d86301d144facf1ede7a36538 100644 (file)
@@ -737,12 +737,13 @@ INITIALIZE_PASS_END(SampleProfileLoader, "sample-profile",
                     "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 22acedc569a131faba53d628b51c0c31ebd8ac1c..e97779968d448862fcd5505d96ed3e195d5ef273 100644 (file)
@@ -49,10 +49,11 @@ void mergeInstrProfile(cl::list<std::string> Inputs, StringRef OutputFilename) {
 
   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 mergeInstrProfile(cl::list<std::string> Inputs, StringRef OutputFilename) {
 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 merge_main(int argc, const char *argv[]) {
 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 @@ int showSampleProfile(std::string Filename, bool ShowCounts,
                       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);