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 |