IceCompileServer.cpp revision 44c3a8046f4c81f9b4476f8c3c72723b584c312d
144c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung//===- subzero/src/IceCompileServer.cpp - Compile server ------------------===// 244c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung// 344c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung// The Subzero Code Generator 444c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung// 544c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung// This file is distributed under the University of Illinois Open Source 644c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung// License. See LICENSE.TXT for details. 744c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung// 844c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung//===----------------------------------------------------------------------===// 944c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung// 1044c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung// This file defines the basic commandline-based compile server. 1144c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung// 1244c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung//===----------------------------------------------------------------------===// 1344c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung 1444c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung#include <fstream> 1544c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung#include <iostream> 1644c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung#include <thread> 1744c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung 1844c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung#include "llvm/Support/FileSystem.h" 1944c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung#include "llvm/Support/raw_os_ostream.h" 2044c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung#include "llvm/Support/SourceMgr.h" 2144c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung#include "llvm/Support/StreamingMemoryObject.h" 2244c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung 2344c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung#include "IceClFlags.h" 2444c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung#include "IceClFlagsExtra.h" 2544c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung#include "IceCompileServer.h" 2644c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung#include "IceELFStreamer.h" 2744c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung#include "IceGlobalContext.h" 2844c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung 2944c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voungnamespace Ice { 3044c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung 3144c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voungnamespace { 3244c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung 3344c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voungstd::unique_ptr<Ostream> getStream(const IceString &Filename) { 3444c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung std::ofstream Ofs; 3544c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung if (Filename != "-") { 3644c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung Ofs.open(Filename.c_str(), std::ofstream::out); 3744c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung return std::unique_ptr<Ostream>(new llvm::raw_os_ostream(Ofs)); 3844c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung } else { 3944c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung return std::unique_ptr<Ostream>(new llvm::raw_os_ostream(std::cout)); 4044c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung } 4144c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung} 4244c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung 4344c3a8046f4c81f9b4476f8c3c72723b584c312dJan VoungErrorCodes getReturnValue(const Ice::ClFlagsExtra &Flags, ErrorCodes Val) { 4444c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung if (Flags.getAlwaysExitSuccess()) 4544c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung return EC_None; 4644c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung return Val; 4744c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung} 4844c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung 4944c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung} // end of anonymous namespace 5044c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung 5144c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voungvoid CLCompileServer::run() { 5244c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung ClFlags::parseFlags(argc, argv); 5344c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung ClFlags Flags; 5444c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung ClFlagsExtra ExtraFlags; 5544c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung ClFlags::getParsedClFlags(Flags); 5644c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung ClFlags::getParsedClFlagsExtra(ExtraFlags); 5744c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung 5844c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung std::unique_ptr<Ostream> Ls = getStream(ExtraFlags.getLogFilename()); 5944c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung Ls->SetUnbuffered(); 6044c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung std::unique_ptr<Ostream> Os; 6144c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung std::unique_ptr<ELFStreamer> ELFStr; 6244c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung switch (Flags.getOutFileType()) { 6344c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung case FT_Elf: { 6444c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung if (ExtraFlags.getOutputFilename() == "-") { 6544c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung *Ls << "Error: writing binary ELF to stdout is unsupported\n"; 6644c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung return transferErrorCode(getReturnValue(ExtraFlags, Ice::EC_Args)); 6744c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung } 6844c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung std::error_code EC; 6944c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung std::unique_ptr<llvm::raw_fd_ostream> FdOs(new llvm::raw_fd_ostream( 7044c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung ExtraFlags.getOutputFilename(), EC, llvm::sys::fs::F_None)); 7144c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung if (EC) { 7244c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung *Ls << "Failed to open output file: " << ExtraFlags.getOutputFilename() 7344c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung << ":\n" << EC.message() << "\n"; 7444c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung return transferErrorCode(getReturnValue(ExtraFlags, Ice::EC_Args)); 7544c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung } 7644c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung ELFStr.reset(new ELFStreamer(*FdOs.get())); 7744c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung Os.reset(FdOs.release()); 7844c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung // NaCl sets st_blksize to 0, and LLVM uses that to pick the 7944c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung // default preferred buffer size. Set to something non-zero. 8044c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung Os->SetBufferSize(1 << 14); 8144c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung } break; 8244c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung case FT_Asm: 8344c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung case FT_Iasm: { 8444c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung Os = getStream(ExtraFlags.getOutputFilename()); 8544c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung Os->SetUnbuffered(); 8644c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung } break; 8744c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung } 8844c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung 8944c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung IceString StrError; 9044c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung std::unique_ptr<llvm::DataStreamer> InputStream( 9144c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung llvm::getDataFileStreamer(ExtraFlags.getIRFilename(), &StrError)); 9244c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung if (!StrError.empty() || !InputStream) { 9344c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung llvm::SMDiagnostic Err(ExtraFlags.getIRFilename(), 9444c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung llvm::SourceMgr::DK_Error, StrError); 9544c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung Err.print(ExtraFlags.getAppName().c_str(), *Ls); 9644c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung return transferErrorCode(getReturnValue(ExtraFlags, Ice::EC_Bitcode)); 9744c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung } 9844c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung 9944c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung Ctx.reset(new GlobalContext(Ls.get(), Os.get(), ELFStr.get(), Flags)); 10044c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung if (Ctx->getFlags().getNumTranslationThreads() != 0) { 10144c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung std::thread CompileThread([this, &ExtraFlags, &InputStream]() { 10244c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung Ctx->initParserThread(); 10344c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung getCompiler().run(ExtraFlags, *Ctx.get(), std::move(InputStream)); 10444c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung }); 10544c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung CompileThread.join(); 10644c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung } else { 10744c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung getCompiler().run(ExtraFlags, *Ctx.get(), std::move(InputStream)); 10844c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung } 10944c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung transferErrorCode(getReturnValue( 11044c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung ExtraFlags, static_cast<ErrorCodes>(Ctx->getErrorStatus()->value()))); 11144c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung} 11244c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung 11344c3a8046f4c81f9b4476f8c3c72723b584c312dJan Voung} // end of namespace Ice 114