| Index: src/IceCompiler.cpp
|
| diff --git a/src/main.cpp b/src/IceCompiler.cpp
|
| similarity index 80%
|
| copy from src/main.cpp
|
| copy to src/IceCompiler.cpp
|
| index 22ab0a100bb025ac73436f1b950aa17a556804ca..a4063391c9f95604bc30c4baf55a3b99e94b18fc 100644
|
| --- a/src/main.cpp
|
| +++ b/src/IceCompiler.cpp
|
| @@ -1,4 +1,4 @@
|
| -//===- subzero/src/main.cpp - Driver for bitcode translation --------------===//
|
| +//===- subzero/src/IceCompiler.cpp - Driver for bitcode translation -------===//
|
| //
|
| // The Subzero Code Generator
|
| //
|
| @@ -15,6 +15,8 @@
|
| //
|
| //===----------------------------------------------------------------------===//
|
|
|
| +#include "IceCompiler.h"
|
| +
|
| #include <fstream>
|
| #include <iostream>
|
|
|
| @@ -30,6 +32,7 @@
|
|
|
| #include "IceCfg.h"
|
| #include "IceClFlags.h"
|
| +#include "IceCompileServer.h"
|
| #include "IceConverter.h"
|
| #include "IceELFObjectWriter.h"
|
| #include "IceELFStreamer.h"
|
| @@ -57,18 +60,19 @@ static cl::list<Ice::VerboseItem> VerboseList(
|
| clEnumValN(Ice::IceV_Most, "most",
|
| "Use all verbose options except 'regalloc' and 'time'"),
|
| clEnumValN(Ice::IceV_None, "none", "No verbosity"), clEnumValEnd));
|
| -static cl::opt<Ice::TargetArch> TargetArch(
|
| - "target", cl::desc("Target architecture:"), cl::init(Ice::Target_X8632),
|
| - cl::values(
|
| - clEnumValN(Ice::Target_X8632, "x8632", "x86-32"),
|
| - clEnumValN(Ice::Target_X8632, "x86-32", "x86-32 (same as x8632)"),
|
| - clEnumValN(Ice::Target_X8632, "x86_32", "x86-32 (same as x8632)"),
|
| - clEnumValN(Ice::Target_X8664, "x8664", "x86-64"),
|
| - clEnumValN(Ice::Target_X8664, "x86-64", "x86-64 (same as x8664)"),
|
| - clEnumValN(Ice::Target_X8664, "x86_64", "x86-64 (same as x8664)"),
|
| - clEnumValN(Ice::Target_ARM32, "arm", "arm32"),
|
| - clEnumValN(Ice::Target_ARM32, "arm32", "arm32 (same as arm)"),
|
| - clEnumValN(Ice::Target_ARM64, "arm64", "arm64"), clEnumValEnd));
|
| +static cl::opt<Ice::TargetArch>
|
| + TArch("target", cl::desc("Target architecture:"),
|
| + cl::init(Ice::Target_X8632),
|
| + cl::values(
|
| + clEnumValN(Ice::Target_X8632, "x8632", "x86-32"),
|
| + clEnumValN(Ice::Target_X8632, "x86-32", "x86-32 (same as x8632)"),
|
| + clEnumValN(Ice::Target_X8632, "x86_32", "x86-32 (same as x8632)"),
|
| + clEnumValN(Ice::Target_X8664, "x8664", "x86-64"),
|
| + clEnumValN(Ice::Target_X8664, "x86-64", "x86-64 (same as x8664)"),
|
| + clEnumValN(Ice::Target_X8664, "x86_64", "x86-64 (same as x8664)"),
|
| + clEnumValN(Ice::Target_ARM32, "arm", "arm32"),
|
| + clEnumValN(Ice::Target_ARM32, "arm32", "arm32 (same as arm)"),
|
| + clEnumValN(Ice::Target_ARM64, "arm64", "arm64"), clEnumValEnd));
|
| static cl::opt<bool> UseSandboxing("sandbox", cl::desc("Use sandboxing"));
|
| static cl::opt<bool>
|
| FunctionSections("ffunction-sections",
|
| @@ -77,13 +81,13 @@ static cl::opt<bool>
|
| DataSections("fdata-sections",
|
| cl::desc("Emit (global) data into separate sections"));
|
| static cl::opt<Ice::OptLevel>
|
| - OptLevel(cl::desc("Optimization level"), cl::init(Ice::Opt_m1),
|
| - cl::value_desc("level"),
|
| - cl::values(clEnumValN(Ice::Opt_m1, "Om1", "-1"),
|
| - clEnumValN(Ice::Opt_m1, "O-1", "-1"),
|
| - clEnumValN(Ice::Opt_0, "O0", "0"),
|
| - clEnumValN(Ice::Opt_1, "O1", "1"),
|
| - clEnumValN(Ice::Opt_2, "O2", "2"), clEnumValEnd));
|
| + OLevel(cl::desc("Optimization level"), cl::init(Ice::Opt_m1),
|
| + cl::value_desc("level"),
|
| + cl::values(clEnumValN(Ice::Opt_m1, "Om1", "-1"),
|
| + clEnumValN(Ice::Opt_m1, "O-1", "-1"),
|
| + clEnumValN(Ice::Opt_0, "O0", "0"),
|
| + clEnumValN(Ice::Opt_1, "O1", "1"),
|
| + clEnumValN(Ice::Opt_2, "O2", "2"), clEnumValEnd));
|
| static cl::opt<std::string> IRFilename(cl::Positional, cl::desc("<IR file>"),
|
| cl::init("-"));
|
| static cl::opt<std::string> OutputFilename("o",
|
| @@ -238,7 +242,7 @@ static struct {
|
| static void ValidateAndGenerateBuildAttributes(Ice::Ostream *Stream) {
|
|
|
| if (Stream)
|
| - *Stream << TargetArch << "\n";
|
| + *Stream << TArch << "\n";
|
|
|
| for (size_t i = 0; i < array_lengthof(ConditionalBuildAttributes); ++i) {
|
| switch (ConditionalBuildAttributes[i].FlagValue) {
|
| @@ -262,7 +266,7 @@ static void ValidateAndGenerateBuildAttributes(Ice::Ostream *Stream) {
|
| }
|
| }
|
|
|
| -int main(int argc, char **argv) {
|
| +void Ice::Compiler::run(int argc, char **argv, Ice::CompileServer &Server) {
|
|
|
| cl::ParseCommandLineOptions(argc, argv);
|
|
|
| @@ -289,12 +293,12 @@ int main(int argc, char **argv) {
|
|
|
| ValidateAndGenerateBuildAttributes(GenerateBuildAtts ? Ls.get() : nullptr);
|
| if (GenerateBuildAtts)
|
| - return GetReturnValue(Ice::EC_None);
|
| + return setReturnValue(GetReturnValue(Ice::EC_None));
|
|
|
| if (!ALLOW_DISABLE_IR_GEN && DisableIRGeneration) {
|
| *Ls << "Error: Build doesn't allow --no-ir-gen when not "
|
| << "ALLOW_DISABLE_IR_GEN!\n";
|
| - return GetReturnValue(Ice::EC_Args);
|
| + return setReturnValue(GetReturnValue(Ice::EC_Args));
|
| }
|
|
|
| Ice::ClFlags Flags;
|
| @@ -322,38 +326,52 @@ int main(int argc, char **argv) {
|
|
|
| // Force -build-on-read=0 for .ll files.
|
| const std::string LLSuffix = ".ll";
|
| - if (IRFilename.length() >= LLSuffix.length() &&
|
| + if (ALLOW_LLVM_IR_AS_INPUT && IRFilename.length() >= LLSuffix.length() &&
|
| IRFilename.compare(IRFilename.length() - LLSuffix.length(),
|
| LLSuffix.length(), LLSuffix) == 0)
|
| BuildOnRead = false;
|
|
|
| - // With the ELF writer, use a raw_fd_ostream to allow seeking.
|
| - // Also don't buffer, otherwise it gets pretty slow.
|
| std::unique_ptr<Ice::Ostream> Os;
|
| std::unique_ptr<Ice::ELFStreamer> ELFStr;
|
| - std::ofstream Ofs;
|
| switch (OutFileType) {
|
| case Ice::FT_Elf: {
|
| if (OutputFilename == "-") {
|
| *Ls << "Error: writing binary ELF to stdout is unsupported\n";
|
| - return GetReturnValue(Ice::EC_Args);
|
| + return setReturnValue(GetReturnValue(Ice::EC_Args));
|
| }
|
| std::error_code EC;
|
| - raw_fd_ostream *FdOs =
|
| - new raw_fd_ostream(OutputFilename, EC, sys::fs::F_None);
|
| - // NaCl sets st_blksize to 0, and LLVM uses that to pick the
|
| - // default preferred buffer size. Set to something non-zero.
|
| - FdOs->SetBufferSize(1 << 14);
|
| - Os.reset(FdOs);
|
| + std::unique_ptr<llvm::raw_fd_ostream> FdOs =
|
| + Server.getOutputStream(OutputFilename, EC);
|
| if (EC) {
|
| *Ls << "Failed to open output file: " << OutputFilename << ":\n"
|
| << EC.message() << "\n";
|
| - return GetReturnValue(Ice::EC_Args);
|
| + return setReturnValue(GetReturnValue(Ice::EC_Args));
|
| }
|
| - ELFStr.reset(new Ice::ELFStreamer(*FdOs));
|
| + ELFStr.reset(new Ice::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 Ice::FT_Asm:
|
| case Ice::FT_Iasm: {
|
| + if (PNACL_BROWSER_TRANSLATOR) {
|
| + *Ls << "Asm/Iasm is not supported under PNACL_BROWSER_TRANSLATOR\n";
|
| + return setReturnValue(GetReturnValue(Ice::EC_Args));
|
| + }
|
| + // Use raw_os_ostream instead of raw_fd_ostream. If both the
|
| + // LogFilename and OutputFilename are stdout, then having
|
| + // Os be a raw_fd_ostream while Ls is a raw_os_ostream backed by
|
| + // a std::ofstream will confuse the buffering and have odd
|
| + // interleavings (even with explicit flushes, for some reason).
|
| + // So, make sure both are the same type of stream. In this case,
|
| + // choose ofstream + raw_os_ostream for both.
|
| + // This avoids asking the compiler server for the output file,
|
| + // which won't work in the PNACL_BROWSER_TRANSLATOR case.
|
| + // An alternative is to choose raw_fd_ostream for both, but then
|
| + // you have to explicitly tell raw_fd_ostream not to own the
|
| + // fd since it is shared by the two streams (you'll get a double-close).
|
| + std::ofstream Ofs;
|
| if (OutputFilename != "-") {
|
| Ofs.open(OutputFilename.c_str(), std::ofstream::out);
|
| Os.reset(new raw_os_ostream(Ofs));
|
| @@ -364,8 +382,8 @@ int main(int argc, char **argv) {
|
| } break;
|
| }
|
|
|
| - Ice::GlobalContext Ctx(Ls.get(), Os.get(), ELFStr.get(), VMask, TargetArch,
|
| - OptLevel, TestPrefix, Flags);
|
| + Ice::GlobalContext Ctx(Ls.get(), Os.get(), ELFStr.get(), VMask, TArch, OLevel,
|
| + TestPrefix, Flags);
|
|
|
| Ice::TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx);
|
|
|
| @@ -381,18 +399,22 @@ int main(int argc, char **argv) {
|
| std::unique_ptr<Ice::PNaClTranslator> PTranslator(
|
| new Ice::PNaClTranslator(&Ctx));
|
| std::string StrError;
|
| - std::unique_ptr<DataStreamer> FileStreamer(
|
| - getDataFileStreamer(IRFilename, &StrError));
|
| + std::unique_ptr<DataStreamer> FileStreamer =
|
| + Server.getInputStream(IRFilename, StrError);
|
| if (!StrError.empty() || !FileStreamer) {
|
| SMDiagnostic Err(IRFilename, SourceMgr::DK_Error, StrError);
|
| Err.print(argv[0], errs());
|
| - return GetReturnValue(Ice::EC_Bitcode);
|
| + return setReturnValue(GetReturnValue(Ice::EC_Bitcode));
|
| }
|
| std::unique_ptr<StreamingMemoryObject> MemObj(
|
| new StreamingMemoryObjectImpl(FileStreamer.release()));
|
| PTranslator->translate(IRFilename, std::move(MemObj));
|
| Translator.reset(PTranslator.release());
|
| } else if (ALLOW_LLVM_IR) {
|
| + if (PNACL_BROWSER_TRANSLATOR) {
|
| + *Ls << "non BuildOnRead is not supported w/ PNACL_BROWSER_TRANSLATOR\n";
|
| + return setReturnValue(GetReturnValue(Ice::EC_Args));
|
| + }
|
| // Parse the input LLVM IR file into a module.
|
| SMDiagnostic Err;
|
| Ice::TimerMarker T1(Ice::TimerStack::TT_parse, &Ctx);
|
| @@ -401,7 +423,7 @@ int main(int argc, char **argv) {
|
| IRFilename, InputFileFormat, Err, Verbose, getGlobalContext());
|
| if (!Mod) {
|
| Err.print(argv[0], errs());
|
| - return GetReturnValue(Ice::EC_Bitcode);
|
| + return setReturnValue(GetReturnValue(Ice::EC_Bitcode));
|
| }
|
|
|
| std::unique_ptr<Ice::Converter> Converter(
|
| @@ -411,7 +433,7 @@ int main(int argc, char **argv) {
|
| } else {
|
| *Ls << "Error: Build doesn't allow LLVM IR, "
|
| << "--build-on-read=0 not allowed\n";
|
| - return GetReturnValue(Ice::EC_Args);
|
| + return setReturnValue(GetReturnValue(Ice::EC_Args));
|
| }
|
|
|
| Ctx.waitForWorkerThreads();
|
| @@ -431,5 +453,5 @@ int main(int argc, char **argv) {
|
| }
|
| const bool FinalStats = true;
|
| Ctx.dumpStats("_FINAL_", FinalStats);
|
| - return GetReturnValue(Ctx.getErrorStatus()->value());
|
| + return setReturnValue(GetReturnValue(Ctx.getErrorStatus()->value()));
|
| }
|
|
|