| Index: src/IceCompileServer.cpp
|
| diff --git a/src/IceCompileServer.cpp b/src/IceCompileServer.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..86ebb0bbf2d06f6fac997a47c566977ad82345e8
|
| --- /dev/null
|
| +++ b/src/IceCompileServer.cpp
|
| @@ -0,0 +1,113 @@
|
| +//===- subzero/src/IceCompileServer.cpp - Compile server ------------------===//
|
| +//
|
| +// The Subzero Code Generator
|
| +//
|
| +// This file is distributed under the University of Illinois Open Source
|
| +// License. See LICENSE.TXT for details.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +//
|
| +// This file defines the basic commandline-based compile server.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +
|
| +#include <fstream>
|
| +#include <iostream>
|
| +#include <thread>
|
| +
|
| +#include "llvm/Support/FileSystem.h"
|
| +#include "llvm/Support/raw_os_ostream.h"
|
| +#include "llvm/Support/SourceMgr.h"
|
| +#include "llvm/Support/StreamingMemoryObject.h"
|
| +
|
| +#include "IceClFlags.h"
|
| +#include "IceClFlagsExtra.h"
|
| +#include "IceCompileServer.h"
|
| +#include "IceELFStreamer.h"
|
| +#include "IceGlobalContext.h"
|
| +
|
| +namespace Ice {
|
| +
|
| +namespace {
|
| +
|
| +std::unique_ptr<Ostream> getStream(const IceString &Filename) {
|
| + std::ofstream Ofs;
|
| + if (Filename != "-") {
|
| + Ofs.open(Filename.c_str(), std::ofstream::out);
|
| + return std::unique_ptr<Ostream>(new llvm::raw_os_ostream(Ofs));
|
| + } else {
|
| + return std::unique_ptr<Ostream>(new llvm::raw_os_ostream(std::cout));
|
| + }
|
| +}
|
| +
|
| +ErrorCodes getReturnValue(const Ice::ClFlagsExtra &Flags, ErrorCodes Val) {
|
| + if (Flags.getAlwaysExitSuccess())
|
| + return EC_None;
|
| + return Val;
|
| +}
|
| +
|
| +} // end of anonymous namespace
|
| +
|
| +void CLCompileServer::run() {
|
| + ClFlags::parseFlags(argc, argv);
|
| + ClFlags Flags;
|
| + ClFlagsExtra ExtraFlags;
|
| + ClFlags::getParsedClFlags(Flags);
|
| + ClFlags::getParsedClFlagsExtra(ExtraFlags);
|
| +
|
| + std::unique_ptr<Ostream> Ls = getStream(ExtraFlags.getLogFilename());
|
| + Ls->SetUnbuffered();
|
| + std::unique_ptr<Ostream> Os;
|
| + std::unique_ptr<ELFStreamer> ELFStr;
|
| + switch (Flags.getOutFileType()) {
|
| + case FT_Elf: {
|
| + if (ExtraFlags.getOutputFilename() == "-") {
|
| + *Ls << "Error: writing binary ELF to stdout is unsupported\n";
|
| + return transferErrorCode(getReturnValue(ExtraFlags, Ice::EC_Args));
|
| + }
|
| + std::error_code EC;
|
| + std::unique_ptr<llvm::raw_fd_ostream> FdOs(new llvm::raw_fd_ostream(
|
| + ExtraFlags.getOutputFilename(), EC, llvm::sys::fs::F_None));
|
| + if (EC) {
|
| + *Ls << "Failed to open output file: " << ExtraFlags.getOutputFilename()
|
| + << ":\n" << EC.message() << "\n";
|
| + return transferErrorCode(getReturnValue(ExtraFlags, Ice::EC_Args));
|
| + }
|
| + ELFStr.reset(new ELFStreamer(*FdOs.get()));
|
| + Os.reset(FdOs.release());
|
| + // NaCl sets st_blksize to 0, and LLVM uses that to pick the
|
| + // default preferred buffer size. Set to something non-zero.
|
| + Os->SetBufferSize(1 << 14);
|
| + } break;
|
| + case FT_Asm:
|
| + case FT_Iasm: {
|
| + Os = getStream(ExtraFlags.getOutputFilename());
|
| + Os->SetUnbuffered();
|
| + } break;
|
| + }
|
| +
|
| + IceString StrError;
|
| + std::unique_ptr<llvm::DataStreamer> InputStream(
|
| + llvm::getDataFileStreamer(ExtraFlags.getIRFilename(), &StrError));
|
| + if (!StrError.empty() || !InputStream) {
|
| + llvm::SMDiagnostic Err(ExtraFlags.getIRFilename(),
|
| + llvm::SourceMgr::DK_Error, StrError);
|
| + Err.print(ExtraFlags.getAppName().c_str(), *Ls);
|
| + return transferErrorCode(getReturnValue(ExtraFlags, Ice::EC_Bitcode));
|
| + }
|
| +
|
| + Ctx.reset(new GlobalContext(Ls.get(), Os.get(), ELFStr.get(), Flags));
|
| + if (Ctx->getFlags().getNumTranslationThreads() != 0) {
|
| + std::thread CompileThread([this, &ExtraFlags, &InputStream]() {
|
| + Ctx->initParserThread();
|
| + getCompiler().run(ExtraFlags, *Ctx.get(), std::move(InputStream));
|
| + });
|
| + CompileThread.join();
|
| + } else {
|
| + getCompiler().run(ExtraFlags, *Ctx.get(), std::move(InputStream));
|
| + }
|
| + transferErrorCode(getReturnValue(
|
| + ExtraFlags, static_cast<ErrorCodes>(Ctx->getErrorStatus()->value())));
|
| +}
|
| +
|
| +} // end of namespace Ice
|
|
|