| Index: src/IceCompiler.cpp
|
| diff --git a/src/IceCompiler.cpp b/src/IceCompiler.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..47f1ba407c2fa86adeec2209b551a0612f69223f
|
| --- /dev/null
|
| +++ b/src/IceCompiler.cpp
|
| @@ -0,0 +1,164 @@
|
| +//===- subzero/src/IceCompiler.cpp - Driver for bitcode translation -------===//
|
| +//
|
| +// The Subzero Code Generator
|
| +//
|
| +// This file is distributed under the University of Illinois Open Source
|
| +// License. See LICENSE.TXT for details.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +//
|
| +// This file defines a driver for translating PNaCl bitcode into native code.
|
| +// It can either directly parse the binary bitcode file, or use LLVM routines to
|
| +// parse a textual bitcode file into LLVM IR and then convert LLVM IR into ICE.
|
| +// In either case, the high-level ICE is then compiled down to native code, as
|
| +// either an ELF object file or a textual asm file.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +
|
| +#include "llvm/ADT/STLExtras.h"
|
| +#include "llvm/IR/LLVMContext.h"
|
| +#include "llvm/IR/Module.h"
|
| +#include "llvm/IRReader/IRReader.h"
|
| +#include "llvm/Support/SourceMgr.h"
|
| +#include "llvm/Support/StreamingMemoryObject.h"
|
| +
|
| +#include "IceCfg.h"
|
| +#include "IceClFlags.h"
|
| +#include "IceClFlagsExtra.h"
|
| +#include "IceCompiler.h"
|
| +#include "IceConverter.h"
|
| +#include "IceELFObjectWriter.h"
|
| +#include "PNaClTranslator.h"
|
| +namespace Ice {
|
| +
|
| +namespace {
|
| +
|
| +struct {
|
| + const char *FlagName;
|
| + int FlagValue;
|
| +} ConditionalBuildAttributes[] = {{"dump", ALLOW_DUMP},
|
| + {"disable_ir_gen", ALLOW_DISABLE_IR_GEN},
|
| + {"llvm_cl", ALLOW_LLVM_CL},
|
| + {"llvm_ir", ALLOW_LLVM_IR},
|
| + {"llvm_ir_as_input", ALLOW_LLVM_IR_AS_INPUT},
|
| + {"minimal_build", ALLOW_MINIMAL_BUILD},
|
| + {"browser_mode", PNACL_BROWSER_TRANSLATOR}};
|
| +
|
| +// Validates values of build attributes. Prints them to Stream if
|
| +// Stream is non-null.
|
| +void ValidateAndGenerateBuildAttributes(const ClFlags &Flags, Ostream *Stream) {
|
| + if (Stream)
|
| + *Stream << Flags.getTargetArch() << "\n";
|
| +
|
| + for (size_t i = 0; i < llvm::array_lengthof(ConditionalBuildAttributes);
|
| + ++i) {
|
| + switch (ConditionalBuildAttributes[i].FlagValue) {
|
| + case 0:
|
| + if (Stream)
|
| + *Stream << "no_" << ConditionalBuildAttributes[i].FlagName << "\n";
|
| + break;
|
| + case 1:
|
| + if (Stream)
|
| + *Stream << "allow_" << ConditionalBuildAttributes[i].FlagName << "\n";
|
| + break;
|
| + default: {
|
| + std::string Buffer;
|
| + llvm::raw_string_ostream StrBuf(Buffer);
|
| + StrBuf << "Flag " << ConditionalBuildAttributes[i].FlagName
|
| + << " must be defined as 0/1. Found: "
|
| + << ConditionalBuildAttributes[i].FlagValue;
|
| + llvm::report_fatal_error(StrBuf.str());
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +} // end of anonymous namespace
|
| +
|
| +void Compiler::run(const Ice::ClFlagsExtra &ExtraFlags, GlobalContext &Ctx,
|
| + std::unique_ptr<llvm::DataStreamer> &&InputStream) {
|
| + ValidateAndGenerateBuildAttributes(
|
| + Ctx.getFlags(),
|
| + ExtraFlags.getGenerateBuildAtts() ? &Ctx.getStrDump() : nullptr);
|
| + if (ExtraFlags.getGenerateBuildAtts())
|
| + return Ctx.getErrorStatus()->assign(EC_None);
|
| +
|
| + if (!ALLOW_DISABLE_IR_GEN && Ctx.getFlags().getDisableIRGeneration()) {
|
| + Ctx.getStrDump() << "Error: Build doesn't allow --no-ir-gen when not "
|
| + << "ALLOW_DISABLE_IR_GEN!\n";
|
| + return Ctx.getErrorStatus()->assign(EC_Args);
|
| + }
|
| +
|
| + // Force -build-on-read=0 for .ll files.
|
| + const std::string LLSuffix = ".ll";
|
| + const IceString &IRFilename = ExtraFlags.getIRFilename();
|
| + bool BuildOnRead = ExtraFlags.getBuildOnRead();
|
| + if (ALLOW_LLVM_IR_AS_INPUT && IRFilename.length() >= LLSuffix.length() &&
|
| + IRFilename.compare(IRFilename.length() - LLSuffix.length(),
|
| + LLSuffix.length(), LLSuffix) == 0)
|
| + BuildOnRead = false;
|
| +
|
| + TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx);
|
| +
|
| + if (Ctx.getFlags().getOutFileType() == FT_Elf) {
|
| + TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx);
|
| + Ctx.getObjectWriter()->writeInitialELFHeader();
|
| + }
|
| +
|
| + Ctx.startWorkerThreads();
|
| +
|
| + std::unique_ptr<Translator> Translator;
|
| + if (BuildOnRead) {
|
| + std::unique_ptr<PNaClTranslator> PTranslator(new PNaClTranslator(&Ctx));
|
| + std::unique_ptr<llvm::StreamingMemoryObject> MemObj(
|
| + new llvm::StreamingMemoryObjectImpl(InputStream.release()));
|
| + PTranslator->translate(IRFilename, std::move(MemObj));
|
| + Translator.reset(PTranslator.release());
|
| + } else if (ALLOW_LLVM_IR) {
|
| + if (PNACL_BROWSER_TRANSLATOR) {
|
| + Ctx.getStrDump()
|
| + << "non BuildOnRead is not supported w/ PNACL_BROWSER_TRANSLATOR\n";
|
| + return Ctx.getErrorStatus()->assign(EC_Args);
|
| + }
|
| + // Parse the input LLVM IR file into a module.
|
| + llvm::SMDiagnostic Err;
|
| + TimerMarker T1(Ice::TimerStack::TT_parse, &Ctx);
|
| + llvm::raw_ostream *Verbose =
|
| + ExtraFlags.getLLVMVerboseErrors() ? &llvm::errs() : nullptr;
|
| + std::unique_ptr<llvm::Module> Mod =
|
| + NaClParseIRFile(IRFilename, ExtraFlags.getInputFileFormat(), Err,
|
| + Verbose, llvm::getGlobalContext());
|
| + if (!Mod) {
|
| + Err.print(ExtraFlags.getAppName().c_str(), llvm::errs());
|
| + return Ctx.getErrorStatus()->assign(EC_Bitcode);
|
| + }
|
| +
|
| + std::unique_ptr<Converter> Converter(new class Converter(Mod.get(), &Ctx));
|
| + Converter->convertToIce();
|
| + Translator.reset(Converter.release());
|
| + } else {
|
| + Ctx.getStrDump() << "Error: Build doesn't allow LLVM IR, "
|
| + << "--build-on-read=0 not allowed\n";
|
| + return Ctx.getErrorStatus()->assign(EC_Args);
|
| + }
|
| +
|
| + Ctx.waitForWorkerThreads();
|
| + Translator->transferErrorCode();
|
| + Translator->emitConstants();
|
| +
|
| + if (Ctx.getFlags().getOutFileType() == FT_Elf) {
|
| + TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx);
|
| + Ctx.getObjectWriter()->setUndefinedSyms(Ctx.getConstantExternSyms());
|
| + Ctx.getObjectWriter()->writeNonUserSections();
|
| + }
|
| + if (Ctx.getFlags().getSubzeroTimingEnabled())
|
| + Ctx.dumpTimers();
|
| + if (Ctx.getFlags().getTimeEachFunction()) {
|
| + const bool DumpCumulative = false;
|
| + Ctx.dumpTimers(GlobalContext::TSK_Funcs, DumpCumulative);
|
| + }
|
| + const bool FinalStats = true;
|
| + Ctx.dumpStats("_FINAL_", FinalStats);
|
| +}
|
| +
|
| +} // end of namespace Ice
|
|
|