Simplify use of formatted_raw_ostream.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 9 Apr 2015 21:06:08 +0000 (21:06 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 9 Apr 2015 21:06:08 +0000 (21:06 +0000)
formatted_raw_ostream is a wrapper over another stream to add column and line
number tracking.

It is used only for asm printing.

This patch moves the its creation down to where we know we are printing
assembly. This has the following advantages:

* Simpler lifetime management: std::unique_ptr
* We don't compute column and line number of object files :-)

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

13 files changed:
include/llvm/MC/MCStreamer.h
include/llvm/Support/FormattedStream.h
include/llvm/Support/TargetRegistry.h
include/llvm/Target/TargetMachine.h
lib/CodeGen/LLVMTargetMachine.cpp
lib/LTO/LTOCodeGenerator.cpp
lib/MC/MCAsmStreamer.cpp
lib/Target/CppBackend/CPPBackend.cpp
lib/Target/CppBackend/CPPTargetMachine.h
lib/Target/TargetMachineC.cpp
tools/gold/gold-plugin.cpp
tools/llc/llc.cpp
tools/llvm-mc/llvm-mc.cpp

index df7610b1d043060f744ab726e814d272f21064a8..91287d0fe704ff9d427e904633fac8d9b9665fa8 100644 (file)
@@ -746,7 +746,8 @@ MCStreamer *createNullStreamer(MCContext &Ctx);
 ///
 /// \param ShowInst - Whether to show the MCInst representation inline with
 /// the assembly.
-MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+MCStreamer *createAsmStreamer(MCContext &Ctx,
+                              std::unique_ptr<formatted_raw_ostream> OS,
                               bool isVerboseAsm, bool useDwarfDirectory,
                               MCInstPrinter *InstPrint, MCCodeEmitter *CE,
                               MCAsmBackend *TAB, bool ShowInst);
index 96e4bfeb0b709b1db40455c73391b0f933bbd001..ad1a26102819f39def0da045295b12e4c865a9fd 100644 (file)
@@ -25,27 +25,11 @@ namespace llvm {
 /// boundaries and querying the number of lines written to the stream.
 ///
 class formatted_raw_ostream : public raw_ostream {
-public:
-  /// DELETE_STREAM - Tell the destructor to delete the held stream.
-  ///
-  static const bool DELETE_STREAM = true;
-
-  /// PRESERVE_STREAM - Tell the destructor to not delete the held
-  /// stream.
-  ///
-  static const bool PRESERVE_STREAM = false;
-
-private:
   /// TheStream - The real stream we output to. We set it to be
   /// unbuffered, since we're already doing our own buffering.
   ///
   raw_ostream *TheStream;
 
-  /// DeleteStream - Do we need to delete TheStream in the
-  /// destructor?
-  ///
-  bool DeleteStream;
-
   /// Position - The current output column and line of the data that's
   /// been flushed and the portion of the buffer that's been
   /// scanned.  The line and column scheme is zero-based.
@@ -73,6 +57,24 @@ private:
   ///
   void ComputePosition(const char *Ptr, size_t size);
 
+  void setStream(raw_ostream &Stream) {
+    releaseStream();
+
+    TheStream = &Stream;
+
+    // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
+    // own buffering, and it doesn't need or want TheStream to do another
+    // layer of buffering underneath. Resize the buffer to what TheStream
+    // had been using, and tell TheStream not to do its own buffering.
+    if (size_t BufferSize = TheStream->GetBufferSize())
+      SetBufferSize(BufferSize);
+    else
+      SetUnbuffered();
+    TheStream->SetUnbuffered();
+
+    Scanned = nullptr;
+  }
+
 public:
   /// formatted_raw_ostream - Open the specified file for
   /// writing. If an error occurs, information about the error is
@@ -84,12 +86,11 @@ public:
   /// so it doesn't want another layer of buffering to be happening
   /// underneath it.
   ///
-  formatted_raw_ostream(raw_ostream &Stream, bool Delete = false)
-      : TheStream(nullptr), DeleteStream(false), Position(0, 0) {
-    setStream(Stream, Delete);
+  formatted_raw_ostream(raw_ostream &Stream)
+      : TheStream(nullptr), Position(0, 0) {
+    setStream(Stream);
   }
-  explicit formatted_raw_ostream()
-      : TheStream(nullptr), DeleteStream(false), Position(0, 0) {
+  explicit formatted_raw_ostream() : TheStream(nullptr), Position(0, 0) {
     Scanned = nullptr;
   }
 
@@ -98,25 +99,6 @@ public:
     releaseStream();
   }
 
-  void setStream(raw_ostream &Stream, bool Delete = false) {
-    releaseStream();
-
-    TheStream = &Stream;
-    DeleteStream = Delete;
-
-    // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
-    // own buffering, and it doesn't need or want TheStream to do another
-    // layer of buffering underneath. Resize the buffer to what TheStream
-    // had been using, and tell TheStream not to do its own buffering.
-    if (size_t BufferSize = TheStream->GetBufferSize())
-      SetBufferSize(BufferSize);
-    else
-      SetUnbuffered();
-    TheStream->SetUnbuffered();
-
-    Scanned = nullptr;
-  }
-
   /// PadToColumn - Align the output to some column number.  If the current
   /// column is already equal to or more than NewCol, PadToColumn inserts one
   /// space.
@@ -151,13 +133,11 @@ public:
 
 private:
   void releaseStream() {
-    // Delete the stream if needed. Otherwise, transfer the buffer
-    // settings from this raw_ostream back to the underlying stream.
+    // Transfer the buffer settings from this raw_ostream back to the underlying
+    // stream.
     if (!TheStream)
       return;
-    if (DeleteStream)
-      delete TheStream;
-    else if (size_t BufferSize = GetBufferSize())
+    if (size_t BufferSize = GetBufferSize())
       TheStream->SetBufferSize(BufferSize);
     else
       TheStream->SetUnbuffered();
index b1b56d6e122452a6029d142fc44df9a919d1e65f..12e35ec10152fa5a61e668475697974e34c94bd5 100644 (file)
@@ -22,6 +22,7 @@
 #include "llvm-c/Disassembler.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Support/CodeGen.h"
+#include "llvm/Support/FormattedStream.h"
 #include <cassert>
 #include <memory>
 #include <string>
@@ -52,7 +53,8 @@ namespace llvm {
   class formatted_raw_ostream;
 
   MCStreamer *createNullStreamer(MCContext &Ctx);
-  MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+  MCStreamer *createAsmStreamer(MCContext &Ctx,
+                                std::unique_ptr<formatted_raw_ostream> OS,
                                 bool isVerboseAsm, bool useDwarfDirectory,
                                 MCInstPrinter *InstPrint, MCCodeEmitter *CE,
                                 MCAsmBackend *TAB, bool ShowInst);
@@ -469,14 +471,16 @@ namespace llvm {
       return S;
     }
 
-    MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+    MCStreamer *createAsmStreamer(MCContext &Ctx,
+                                  std::unique_ptr<formatted_raw_ostream> OS,
                                   bool IsVerboseAsm, bool UseDwarfDirectory,
                                   MCInstPrinter *InstPrint, MCCodeEmitter *CE,
                                   MCAsmBackend *TAB, bool ShowInst) const {
-      MCStreamer *S =
-          llvm::createAsmStreamer(Ctx, OS, IsVerboseAsm, UseDwarfDirectory,
-                                  InstPrint, CE, TAB, ShowInst);
-      createAsmTargetStreamer(*S, OS, InstPrint, IsVerboseAsm);
+      formatted_raw_ostream &OSRef = *OS;
+      MCStreamer *S = llvm::createAsmStreamer(Ctx, std::move(OS), IsVerboseAsm,
+                                              UseDwarfDirectory, InstPrint, CE,
+                                              TAB, ShowInst);
+      createAsmTargetStreamer(*S, OSRef, InstPrint, IsVerboseAsm);
       return S;
     }
 
index 1b26ccef2b61ff77d2253f91c5934ef14ddef627..58532180e484d326aa2108fedfa3f2f2d0a91d2b 100644 (file)
@@ -207,8 +207,7 @@ public:
   /// emitted.  Typically this will involve several steps of code generation.
   /// This method should return true if emission of this file type is not
   /// supported, or false on success.
-  virtual bool addPassesToEmitFile(PassManagerBase &,
-                                   formatted_raw_ostream &,
+  virtual bool addPassesToEmitFile(PassManagerBase &, raw_ostream &,
                                    CodeGenFileType,
                                    bool /*DisableVerify*/ = true,
                                    AnalysisID /*StartAfter*/ = nullptr,
@@ -257,7 +256,7 @@ public:
 
   /// Add passes to the specified pass manager to get the specified file
   /// emitted.  Typically this will involve several steps of code generation.
-  bool addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out,
+  bool addPassesToEmitFile(PassManagerBase &PM, raw_ostream &Out,
                            CodeGenFileType FileType, bool DisableVerify = true,
                            AnalysisID StartAfter = nullptr,
                            AnalysisID StopAfter = nullptr) override;
index 301484461956d529df71b3d6d724f61f1871152a..5e6bfb74537da6917e13eee9b19adcc7e739dce9 100644 (file)
@@ -140,12 +140,9 @@ static MCContext *addPassesToGenerateCode(LLVMTargetMachine *TM,
   return &MMI->getContext();
 }
 
-bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
-                                            formatted_raw_ostream &Out,
-                                            CodeGenFileType FileType,
-                                            bool DisableVerify,
-                                            AnalysisID StartAfter,
-                                            AnalysisID StopAfter) {
+bool LLVMTargetMachine::addPassesToEmitFile(
+    PassManagerBase &PM, raw_ostream &Out, CodeGenFileType FileType,
+    bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter) {
   // Add common CodeGen passes.
   MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify,
                                                StartAfter, StopAfter);
@@ -184,8 +181,9 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
 
     MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(),
                                                        TargetCPU);
+    auto FOut = llvm::make_unique<formatted_raw_ostream>(Out);
     MCStreamer *S = getTarget().createAsmStreamer(
-        *Context, Out, Options.MCOptions.AsmVerbose,
+        *Context, std::move(FOut), Options.MCOptions.AsmVerbose,
         Options.MCOptions.MCUseDwarfDirectory, InstPrinter, MCE, MAB,
         Options.MCOptions.ShowMCInst);
     AsmStreamer.reset(S);
index ad73ddc5d7a3d483379b38e77488c15edd56b443..2bcdc27e9658aa0af1d165f2cbbba0090979185c 100644 (file)
@@ -38,7 +38,6 @@
 #include "llvm/MC/SubtargetFeature.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
-#include "llvm/Support/FormattedStream.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Signals.h"
@@ -574,13 +573,11 @@ bool LTOCodeGenerator::compileOptimized(raw_ostream &out, std::string &errMsg) {
 
   legacy::PassManager codeGenPasses;
 
-  formatted_raw_ostream Out(out);
-
   // If the bitcode files contain ARC code and were compiled with optimization,
   // the ObjCARCContractPass must be run, so do it unconditionally here.
   codeGenPasses.add(createObjCARCContractPass());
 
-  if (TargetMach->addPassesToEmitFile(codeGenPasses, Out,
+  if (TargetMach->addPassesToEmitFile(codeGenPasses, out,
                                       TargetMachine::CGFT_ObjectFile)) {
     errMsg = "target file type not supported";
     return false;
index ab6ae2586ead742713ed9a44111011efa8ed2b54..144d35553b8a980e85cb59dfd536fac55340f937 100644 (file)
@@ -37,6 +37,7 @@ using namespace llvm;
 namespace {
 
 class MCAsmStreamer final : public MCStreamer {
+  std::unique_ptr<formatted_raw_ostream> OSOwner;
   formatted_raw_ostream &OS;
   const MCAsmInfo *MAI;
   std::unique_ptr<MCInstPrinter> InstPrinter;
@@ -55,14 +56,15 @@ class MCAsmStreamer final : public MCStreamer {
   void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
 
 public:
-  MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
+  MCAsmStreamer(MCContext &Context, std::unique_ptr<formatted_raw_ostream> os,
                 bool isVerboseAsm, bool useDwarfDirectory,
                 MCInstPrinter *printer, MCCodeEmitter *emitter,
                 MCAsmBackend *asmbackend, bool showInst)
-      : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()),
-        InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend),
-        CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
-        ShowInst(showInst), UseDwarfDirectory(useDwarfDirectory) {
+      : MCStreamer(Context), OSOwner(std::move(os)), OS(*OSOwner),
+        MAI(Context.getAsmInfo()), InstPrinter(printer), Emitter(emitter),
+        AsmBackend(asmbackend), CommentStream(CommentToEmit),
+        IsVerboseAsm(isVerboseAsm), ShowInst(showInst),
+        UseDwarfDirectory(useDwarfDirectory) {
     if (InstPrinter && IsVerboseAsm)
       InstPrinter->setCommentStream(CommentStream);
   }
@@ -1312,10 +1314,10 @@ void MCAsmStreamer::FinishImpl() {
 }
 
 MCStreamer *llvm::createAsmStreamer(MCContext &Context,
-                                    formatted_raw_ostream &OS,
+                                    std::unique_ptr<formatted_raw_ostream> OS,
                                     bool isVerboseAsm, bool useDwarfDirectory,
                                     MCInstPrinter *IP, MCCodeEmitter *CE,
                                     MCAsmBackend *MAB, bool ShowInst) {
-  return new MCAsmStreamer(Context, OS, isVerboseAsm, useDwarfDirectory, IP, CE,
-                           MAB, ShowInst);
+  return new MCAsmStreamer(Context, std::move(OS), isVerboseAsm,
+                           useDwarfDirectory, IP, CE, MAB, ShowInst);
 }
index d0e2010abfd426e090003f6109c9b7e03da075f3..8a9437b75fff5808eec4856300e0030918f54d6c 100644 (file)
@@ -15,6 +15,7 @@
 #include "CPPTargetMachine.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/Config/config.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Constants.h"
@@ -91,6 +92,7 @@ namespace {
   /// CppWriter - This class is the main chunk of code that converts an LLVM
   /// module to a C++ translation unit.
   class CppWriter : public ModulePass {
+    std::unique_ptr<formatted_raw_ostream> OutOwner;
     formatted_raw_ostream &Out;
     const Module *TheModule;
     uint64_t uniqueNum;
@@ -105,8 +107,9 @@ namespace {
 
   public:
     static char ID;
-    explicit CppWriter(formatted_raw_ostream &o) :
-      ModulePass(ID), Out(o), uniqueNum(0), is_inline(false), indent_level(0){}
+    explicit CppWriter(std::unique_ptr<formatted_raw_ostream> o)
+        : ModulePass(ID), OutOwner(std::move(o)), Out(*OutOwner), uniqueNum(0),
+          is_inline(false), indent_level(0) {}
 
     const char *getPassName() const override { return "C++ backend"; }
 
@@ -2146,13 +2149,14 @@ char CppWriter::ID = 0;
 //                       External Interface declaration
 //===----------------------------------------------------------------------===//
 
-bool CPPTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
-                                           formatted_raw_ostream &o,
+bool CPPTargetMachine::addPassesToEmitFile(PassManagerBase &PM, raw_ostream &o,
                                            CodeGenFileType FileType,
                                            bool DisableVerify,
                                            AnalysisID StartAfter,
                                            AnalysisID StopAfter) {
-  if (FileType != TargetMachine::CGFT_AssemblyFile) return true;
-  PM.add(new CppWriter(o));
+  if (FileType != TargetMachine::CGFT_AssemblyFile)
+    return true;
+  auto FOut = llvm::make_unique<formatted_raw_ostream>(o);
+  PM.add(new CppWriter(std::move(FOut)));
   return false;
 }
index 678a932cb28686d14ad168e7c374bc826995ecc6..04f81e9e9665c16a5af7abb39e8ca1ef978f90aa 100644 (file)
@@ -29,7 +29,7 @@ struct CPPTargetMachine : public TargetMachine {
       : TargetMachine(T, "", TT, CPU, FS, Options) {}
 
 public:
-  bool addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out,
+  bool addPassesToEmitFile(PassManagerBase &PM, raw_ostream &Out,
                            CodeGenFileType FileType, bool DisableVerify,
                            AnalysisID StartAfter,
                            AnalysisID StopAfter) override;
index aaa66d3bf6159a52e239b1efad7a490b32366cdd..afba80f0f050754319599fa15dcae1f5179e59d4 100644 (file)
@@ -183,7 +183,7 @@ void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,
 }
 
 static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,
-                                      formatted_raw_ostream &OS,
+                                      raw_ostream &OS,
                                       LLVMCodeGenFileType codegen,
                                       char **ErrorMessage) {
   TargetMachine* TM = unwrap(T);
@@ -231,8 +231,7 @@ LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
     *ErrorMessage = strdup(EC.message().c_str());
     return true;
   }
-  formatted_raw_ostream destf(dest);
-  bool Result = LLVMTargetMachineEmit(T, M, destf, codegen, ErrorMessage);
+  bool Result = LLVMTargetMachineEmit(T, M, dest, codegen, ErrorMessage);
   dest.flush();
   return Result;
 }
@@ -242,8 +241,7 @@ LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T,
   LLVMMemoryBufferRef *OutMemBuf) {
   SmallString<0> CodeString;
   raw_svector_ostream OStream(CodeString);
-  formatted_raw_ostream Out(OStream);
-  bool Result = LLVMTargetMachineEmit(T, M, Out, codegen, ErrorMessage);
+  bool Result = LLVMTargetMachineEmit(T, M, OStream, codegen, ErrorMessage);
   OStream.flush();
 
   StringRef Data = OStream.str();
index 93ce3bc0f446b2fbd1223dd3055b9f6252007fd0..2c7bf5a64eef3b5e5f7b8185fce2d31373911309 100644 (file)
@@ -31,7 +31,7 @@
 #include "llvm/Linker/Linker.h"
 #include "llvm/MC/SubtargetFeature.h"
 #include "llvm/Object/IRObjectFile.h"
-#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -804,9 +804,8 @@ static void codegen(Module &M) {
 
   {
     raw_fd_ostream OS(FD, true);
-    formatted_raw_ostream FOS(OS);
 
-    if (TM->addPassesToEmitFile(CodeGenPasses, FOS,
+    if (TM->addPassesToEmitFile(CodeGenPasses, OS,
                                 TargetMachine::CGFT_ObjectFile))
       message(LDPL_FATAL, "Failed to setup codegen");
     CodeGenPasses.run(M);
index d46cbb3181b6898576f533f9b2414cbbd49bef1c..c20adfd9021f3218f0a184761a729935cc9c7a7d 100644 (file)
@@ -335,8 +335,6 @@ static int compileModule(char **argv, LLVMContext &Context) {
              << ": warning: ignoring -mc-relax-all because filetype != obj";
 
   {
-    formatted_raw_ostream FOS(Out->os());
-
     AnalysisID StartAfterID = nullptr;
     AnalysisID StopAfterID = nullptr;
     const PassRegistry *PR = PassRegistry::getPassRegistry();
@@ -358,7 +356,7 @@ static int compileModule(char **argv, LLVMContext &Context) {
     }
 
     // Ask the target to add backend passes as necessary.
-    if (Target->addPassesToEmitFile(PM, FOS, FileType, NoVerify,
+    if (Target->addPassesToEmitFile(PM, Out->os(), FileType, NoVerify,
                                     StartAfterID, StopAfterID)) {
       errs() << argv[0] << ": target does not support generation of this"
              << " file type!\n";
index 9944f184ce8cc342f86056bfb1a27a802521699f..58fe233fce1580a4557a5111b804d289f4b5cf2f 100644 (file)
@@ -439,7 +439,6 @@ int main(int argc, char **argv) {
   if (!Out)
     return 1;
 
-  formatted_raw_ostream FOS(Out->os());
   std::unique_ptr<MCStreamer> Str;
 
   std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
@@ -461,9 +460,10 @@ int main(int argc, char **argv) {
       CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
       MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
     }
-    Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/ true,
-                                           /*useDwarfDirectory*/ true, IP, CE,
-                                           MAB, ShowInst));
+    auto FOut = llvm::make_unique<formatted_raw_ostream>(Out->os());
+    Str.reset(TheTarget->createAsmStreamer(
+        Ctx, std::move(FOut), /*asmverbose*/ true,
+        /*useDwarfDirectory*/ true, IP, CE, MAB, ShowInst));
 
   } else if (FileType == OFT_Null) {
     Str.reset(TheTarget->createNullStreamer(Ctx));
@@ -471,8 +471,8 @@ int main(int argc, char **argv) {
     assert(FileType == OFT_ObjectFile && "Invalid file type!");
     MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
     MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
-    Str.reset(TheTarget->createMCObjectStreamer(TheTriple, Ctx, *MAB, FOS, CE,
-                                                *STI, RelaxAll,
+    Str.reset(TheTarget->createMCObjectStreamer(TheTriple, Ctx, *MAB, Out->os(),
+                                                CE, *STI, RelaxAll,
                                                 /*DWARFMustBeAtTheEnd*/ false));
     if (NoExecStack)
       Str->InitSections(true);