Skip to content

Commit

Permalink
Simplify use of formatted_raw_ostream.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
espindola committed Apr 9, 2015
1 parent 66649e0 commit 427c073
Show file tree
Hide file tree
Showing 13 changed files with 78 additions and 98 deletions.
3 changes: 2 additions & 1 deletion include/llvm/MC/MCStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
70 changes: 25 additions & 45 deletions include/llvm/Support/FormattedStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -73,6 +57,24 @@ class formatted_raw_ostream : public raw_ostream {
///
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
Expand All @@ -84,12 +86,11 @@ class formatted_raw_ostream : public raw_ostream {
/// 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;
}

Expand All @@ -98,25 +99,6 @@ class formatted_raw_ostream : public raw_ostream {
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.
Expand Down Expand Up @@ -151,13 +133,11 @@ class formatted_raw_ostream : public raw_ostream {

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();
Expand Down
16 changes: 10 additions & 6 deletions include/llvm/Support/TargetRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down
5 changes: 2 additions & 3 deletions include/llvm/Target/TargetMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,7 @@ class TargetMachine {
/// 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,
Expand Down Expand Up @@ -257,7 +256,7 @@ class LLVMTargetMachine : public TargetMachine {

/// 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;
Expand Down
12 changes: 5 additions & 7 deletions lib/CodeGen/LLVMTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 1 addition & 4 deletions lib/LTO/LTOCodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand Down
18 changes: 10 additions & 8 deletions lib/MC/MCAsmStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
}
16 changes: 10 additions & 6 deletions lib/Target/CppBackend/CPPBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand All @@ -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"; }

Expand Down Expand Up @@ -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;
}
2 changes: 1 addition & 1 deletion lib/Target/CppBackend/CPPTargetMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 3 additions & 5 deletions lib/Target/TargetMachineC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand All @@ -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();
Expand Down
5 changes: 2 additions & 3 deletions tools/gold/gold-plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 1 addition & 3 deletions tools/llc/llc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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";
Expand Down
Loading

0 comments on commit 427c073

Please sign in to comment.