Skip to content

Commit

Permalink
Use raw_pwrite_stream in clang.
Browse files Browse the repository at this point in the history
This is a small improvement to -emit-pth and allows llvm to start requiring it.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@234897 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
espindola committed Apr 14, 2015
1 parent 6ad734a commit 23ddbdd
Show file tree
Hide file tree
Showing 11 changed files with 85 additions and 63 deletions.
2 changes: 2 additions & 0 deletions include/clang/Basic/LLVM.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ namespace llvm {
class RefCountedBaseVPTR;

class raw_ostream;
class raw_pwrite_stream;
// TODO: DenseMap, ...
}

Expand Down Expand Up @@ -76,6 +77,7 @@ namespace clang {
using llvm::RefCountedBaseVPTR;

using llvm::raw_ostream;
using llvm::raw_pwrite_stream;
} // end namespace clang.

#endif
2 changes: 1 addition & 1 deletion include/clang/CodeGen/BackendUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace clang {
void EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts,
const TargetOptions &TOpts, const LangOptions &LOpts,
StringRef TDesc, llvm::Module *M, BackendAction Action,
raw_ostream *OS);
raw_pwrite_stream *OS);
}

#endif
25 changes: 14 additions & 11 deletions include/clang/Frontend/CompilerInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ class CompilerInstance : public ModuleLoader {
TempFilename(std::move(O.TempFilename)), OS(std::move(O.OS)) {}
};

/// If the output doesn't support seeking (terminal, pipe). we switch
/// the stream to a buffer_ostream. These are the buffer and the original
/// stream.
std::unique_ptr<llvm::raw_fd_ostream> NonSeekStream;

/// The list of active output files.
std::list<OutputFile> OutputFiles;

Expand Down Expand Up @@ -631,21 +636,19 @@ class CompilerInstance : public ModuleLoader {
/// atomically replace the target output on success).
///
/// \return - Null on error.
llvm::raw_fd_ostream *
createDefaultOutputFile(bool Binary = true, StringRef BaseInput = "",
StringRef Extension = "");
raw_pwrite_stream *createDefaultOutputFile(bool Binary = true,
StringRef BaseInput = "",
StringRef Extension = "");

/// Create a new output file and add it to the list of tracked output files,
/// optionally deriving the output path name.
///
/// \return - Null on error.
llvm::raw_fd_ostream *
createOutputFile(StringRef OutputPath,
bool Binary, bool RemoveFileOnSignal,
StringRef BaseInput,
StringRef Extension,
bool UseTemporary,
bool CreateMissingDirectories = false);
raw_pwrite_stream *createOutputFile(StringRef OutputPath, bool Binary,
bool RemoveFileOnSignal,
StringRef BaseInput, StringRef Extension,
bool UseTemporary,
bool CreateMissingDirectories = false);

/// Create a new output file, optionally deriving the output path name.
///
Expand All @@ -672,7 +675,7 @@ class CompilerInstance : public ModuleLoader {
/// stored here on success.
/// \param TempPathName [out] - If given, the temporary file path name
/// will be stored here on success.
static std::unique_ptr<llvm::raw_fd_ostream>
std::unique_ptr<raw_pwrite_stream>
createOutputFile(StringRef OutputPath, std::error_code &Error, bool Binary,
bool RemoveFileOnSignal, StringRef BaseInput,
StringRef Extension, bool UseTemporary,
Expand Down
5 changes: 2 additions & 3 deletions include/clang/Frontend/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,8 @@ void AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders = false,
StringRef OutputPath = "",
bool ShowDepth = true, bool MSStyle = false);

/// CacheTokens - Cache tokens for use with PCH. Note that this requires
/// a seekable stream.
void CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS);
/// Cache tokens for use with PCH. Note that this requires a seekable stream.
void CacheTokens(Preprocessor &PP, raw_pwrite_stream *OS);

/// The ChainedIncludesSource class converts headers to chained PCHs in
/// memory, mainly for testing.
Expand Down
16 changes: 9 additions & 7 deletions lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class EmitAssemblyHelper {

void CreatePasses();

/// CreateTargetMachine - Generates the TargetMachine.
/// Generates the TargetMachine.
/// Returns Null if it is unable to create the target machine.
/// Some of our clang tests specify triples which are not built
/// into clang. This is okay because these tests check the generated
Expand All @@ -106,10 +106,10 @@ class EmitAssemblyHelper {
/// the requested target.
TargetMachine *CreateTargetMachine(bool MustCreateTM);

/// AddEmitPasses - Add passes necessary to emit assembly or LLVM IR.
/// Add passes necessary to emit assembly or LLVM IR.
///
/// \return True on success.
bool AddEmitPasses(BackendAction Action, raw_ostream &OS);
bool AddEmitPasses(BackendAction Action, raw_pwrite_stream &OS);

public:
EmitAssemblyHelper(DiagnosticsEngine &_Diags,
Expand All @@ -132,7 +132,7 @@ class EmitAssemblyHelper {

std::unique_ptr<TargetMachine> TM;

void EmitAssembly(BackendAction Action, raw_ostream *OS);
void EmitAssembly(BackendAction Action, raw_pwrite_stream *OS);
};

// We need this wrapper to access LangOpts and CGOpts from extension functions
Expand Down Expand Up @@ -545,7 +545,8 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
return TM;
}

bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, raw_ostream &OS) {
bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action,
raw_pwrite_stream &OS) {

// Create the code generator passes.
legacy::PassManager *PM = getCodeGenPasses();
Expand Down Expand Up @@ -582,7 +583,8 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, raw_ostream &OS) {
return true;
}

void EmitAssemblyHelper::EmitAssembly(BackendAction Action, raw_ostream *OS) {
void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
raw_pwrite_stream *OS) {
TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr);

bool UsesCodeGen = (Action != Backend_EmitNothing &&
Expand Down Expand Up @@ -644,7 +646,7 @@ void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
const clang::TargetOptions &TOpts,
const LangOptions &LOpts, StringRef TDesc,
Module *M, BackendAction Action,
raw_ostream *OS) {
raw_pwrite_stream *OS) {
EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M);

AsmHelper.EmitAssembly(Action, OS);
Expand Down
13 changes: 6 additions & 7 deletions lib/CodeGen/CodeGenAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace clang {
const CodeGenOptions &CodeGenOpts;
const TargetOptions &TargetOpts;
const LangOptions &LangOpts;
raw_ostream *AsmOutStream;
raw_pwrite_stream *AsmOutStream;
ASTContext *Context;

Timer LLVMIRGeneration;
Expand All @@ -61,7 +61,7 @@ namespace clang {
const TargetOptions &targetopts,
const LangOptions &langopts, bool TimePasses,
const std::string &infile, llvm::Module *LinkModule,
raw_ostream *OS, LLVMContext &C,
raw_pwrite_stream *OS, LLVMContext &C,
CoverageSourceInfo *CoverageInfo = nullptr)
: Diags(_Diags), Action(action), CodeGenOpts(compopts),
TargetOpts(targetopts), LangOpts(langopts), AsmOutStream(OS),
Expand Down Expand Up @@ -601,9 +601,8 @@ llvm::LLVMContext *CodeGenAction::takeLLVMContext() {
return VMContext;
}

static raw_ostream *GetOutputStream(CompilerInstance &CI,
StringRef InFile,
BackendAction Action) {
static raw_pwrite_stream *
GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) {
switch (Action) {
case Backend_EmitAssembly:
return CI.createDefaultOutputFile(false, InFile, "s");
Expand All @@ -625,7 +624,7 @@ static raw_ostream *GetOutputStream(CompilerInstance &CI,
std::unique_ptr<ASTConsumer>
CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
BackendAction BA = static_cast<BackendAction>(Act);
std::unique_ptr<raw_ostream> OS(GetOutputStream(CI, InFile, BA));
std::unique_ptr<raw_pwrite_stream> OS(GetOutputStream(CI, InFile, BA));
if (BA != Backend_EmitNothing && !OS)
return nullptr;

Expand Down Expand Up @@ -678,7 +677,7 @@ void CodeGenAction::ExecuteAction() {
if (getCurrentFileKind() == IK_LLVM_IR) {
BackendAction BA = static_cast<BackendAction>(Act);
CompilerInstance &CI = getCompilerInstance();
raw_ostream *OS = GetOutputStream(CI, getCurrentFile(), BA);
raw_pwrite_stream *OS = GetOutputStream(CI, getCurrentFile(), BA);
if (BA != Backend_EmitNothing && !OS)
return;

Expand Down
29 changes: 19 additions & 10 deletions lib/Frontend/CacheTokens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ class PTHWriter {
typedef llvm::StringMap<OffsetOpt, llvm::BumpPtrAllocator> CachedStrsTy;

IDMap IM;
llvm::raw_fd_ostream& Out;
raw_pwrite_stream &Out;
Preprocessor& PP;
uint32_t idcount;
PTHMap PM;
Expand Down Expand Up @@ -236,8 +236,8 @@ class PTHWriter {
Offset EmitCachedSpellings();

public:
PTHWriter(llvm::raw_fd_ostream& out, Preprocessor& pp)
: Out(out), PP(pp), idcount(0), CurStrOffset(0) {}
PTHWriter(raw_pwrite_stream &out, Preprocessor &pp)
: Out(out), PP(pp), idcount(0), CurStrOffset(0) {}

PTHMap &getPM() { return PM; }
void GeneratePTH(const std::string &MainFile);
Expand Down Expand Up @@ -468,6 +468,16 @@ Offset PTHWriter::EmitCachedSpellings() {
return SpellingsOff;
}

static uint32_t swap32le(uint32_t X) {
return llvm::support::endian::byte_swap<uint32_t, llvm::support::little>(X);
}

static void pwrite32le(raw_pwrite_stream &OS, uint32_t Val, uint64_t &Off) {
uint32_t LEVal = swap32le(Val);
OS.pwrite(reinterpret_cast<const char *>(&LEVal), 4, Off);
Off += 4;
}

void PTHWriter::GeneratePTH(const std::string &MainFile) {
// Generate the prologue.
Out << "cfe-pth" << '\0';
Expand Down Expand Up @@ -520,11 +530,11 @@ void PTHWriter::GeneratePTH(const std::string &MainFile) {
Offset FileTableOff = EmitFileTable();

// Finally, write the prologue.
Out.seek(PrologueOffset);
Emit32(IdTableOff.first);
Emit32(IdTableOff.second);
Emit32(FileTableOff);
Emit32(SpellingOff);
uint64_t Off = PrologueOffset;
pwrite32le(Out, IdTableOff.first, Off);
pwrite32le(Out, IdTableOff.second, Off);
pwrite32le(Out, FileTableOff, Off);
pwrite32le(Out, SpellingOff, Off);
}

namespace {
Expand Down Expand Up @@ -559,8 +569,7 @@ class StatListener : public FileSystemStatCache {
};
} // end anonymous namespace


void clang::CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS) {
void clang::CacheTokens(Preprocessor &PP, raw_pwrite_stream *OS) {
// Get the name of the main file.
const SourceManager &SrcMgr = PP.getSourceManager();
const FileEntry *MainFile = SrcMgr.getFileEntryForID(SrcMgr.getMainFileID());
Expand Down
30 changes: 17 additions & 13 deletions lib/Frontend/CompilerInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,11 +550,11 @@ void CompilerInstance::clearOutputFiles(bool EraseFiles) {

}
OutputFiles.clear();
NonSeekStream.reset();
}

llvm::raw_fd_ostream *
CompilerInstance::createDefaultOutputFile(bool Binary,
StringRef InFile,
raw_pwrite_stream *
CompilerInstance::createDefaultOutputFile(bool Binary, StringRef InFile,
StringRef Extension) {
return createOutputFile(getFrontendOpts().OutputFile, Binary,
/*RemoveFileOnSignal=*/true, InFile, Extension,
Expand All @@ -568,16 +568,14 @@ llvm::raw_null_ostream *CompilerInstance::createNullOutputFile() {
return Ret;
}

llvm::raw_fd_ostream *
CompilerInstance::createOutputFile(StringRef OutputPath,
bool Binary, bool RemoveFileOnSignal,
StringRef InFile,
StringRef Extension,
bool UseTemporary,
raw_pwrite_stream *
CompilerInstance::createOutputFile(StringRef OutputPath, bool Binary,
bool RemoveFileOnSignal, StringRef InFile,
StringRef Extension, bool UseTemporary,
bool CreateMissingDirectories) {
std::string OutputPathName, TempPathName;
std::error_code EC;
std::unique_ptr<llvm::raw_fd_ostream> OS = createOutputFile(
std::unique_ptr<raw_pwrite_stream> OS = createOutputFile(
OutputPath, EC, Binary, RemoveFileOnSignal, InFile, Extension,
UseTemporary, CreateMissingDirectories, &OutputPathName, &TempPathName);
if (!OS) {
Expand All @@ -586,7 +584,7 @@ CompilerInstance::createOutputFile(StringRef OutputPath,
return nullptr;
}

llvm::raw_fd_ostream *Ret = OS.get();
raw_pwrite_stream *Ret = OS.get();
// Add the output file -- but don't try to remove "-", since this means we are
// using stdin.
addOutputFile(OutputFile((OutputPathName != "-") ? OutputPathName : "",
Expand All @@ -595,7 +593,7 @@ CompilerInstance::createOutputFile(StringRef OutputPath,
return Ret;
}

std::unique_ptr<llvm::raw_fd_ostream> CompilerInstance::createOutputFile(
std::unique_ptr<llvm::raw_pwrite_stream> CompilerInstance::createOutputFile(
StringRef OutputPath, std::error_code &Error, bool Binary,
bool RemoveFileOnSignal, StringRef InFile, StringRef Extension,
bool UseTemporary, bool CreateMissingDirectories,
Expand Down Expand Up @@ -683,7 +681,13 @@ std::unique_ptr<llvm::raw_fd_ostream> CompilerInstance::createOutputFile(
if (TempPathName)
*TempPathName = TempFile;

return OS;
if (!Binary || OS->supportsSeeking())
return std::move(OS);

auto B = llvm::make_unique<llvm::buffer_ostream>(*OS);
assert(!NonSeekStream);
NonSeekStream = std::move(OS);
return std::move(B);
}

// Initialization Utilities
Expand Down
7 changes: 1 addition & 6 deletions lib/Frontend/FrontendActions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,15 +599,10 @@ void DumpTokensAction::ExecuteAction() {

void GeneratePTHAction::ExecuteAction() {
CompilerInstance &CI = getCompilerInstance();
llvm::raw_fd_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
raw_pwrite_stream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
if (!OS)
return;

if (!OS->supportsSeeking()) {
// FIXME: Don't fail this way.
llvm::report_fatal_error("PTH requires a seekable file for output!");
}

CacheTokens(CI.getPreprocessor(), OS);
}

Expand Down
4 changes: 2 additions & 2 deletions test/PCH/emit-pth.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-pth -o %t1 %s
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-pth -o - %s > %t2
// RUN: cmp %t1 %t2
// RUN: not %clang_cc1 -triple i386-unknown-unknown -emit-pth -o - %s 2>&1 | \
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-pth -o - %s | \
// RUN: FileCheck %s

// CHECK: PTH requires a seekable file for output!
// CHECK: cfe-pth
15 changes: 12 additions & 3 deletions tools/driver/cc1as_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
MAI->setCompressDebugSections(true);

bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
std::unique_ptr<raw_fd_ostream> Out = getOutputStream(Opts, Diags, IsBinary);
if (!Out)
std::unique_ptr<raw_fd_ostream> FDOS = getOutputStream(Opts, Diags, IsBinary);
if (!FDOS)
return true;

// FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
Expand Down Expand Up @@ -355,6 +355,9 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
std::unique_ptr<MCSubtargetInfo> STI(
TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));

raw_pwrite_stream *Out = FDOS.get();
std::unique_ptr<buffer_ostream> BOS;

// FIXME: There is a bit of code duplication with addPassesToEmitFile.
if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
MCInstPrinter *IP = TheTarget->createMCInstPrinter(
Expand All @@ -374,6 +377,11 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
} else {
assert(Opts.OutputType == AssemblerInvocation::FT_Obj &&
"Invalid file type!");
if (!FDOS->supportsSeeking()) {
BOS = make_unique<buffer_ostream>(*FDOS);
Out = BOS.get();
}

MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple,
Opts.CPU);
Expand Down Expand Up @@ -402,7 +410,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
}

// Close the output stream early.
Out.reset();
BOS.reset();
FDOS.reset();

// Delete output file if there were errors.
if (Failed && Opts.OutputPath != "-")
Expand Down

0 comments on commit 23ddbdd

Please sign in to comment.