//===- 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.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Defines a driver for translating PNaCl bitcode into native code.
///
/// The driver 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 "IceCompiler.h"

#include "IceBuildDefs.h"
#include "IceCfg.h"
#include "IceClFlags.h"
#include "IceConverter.h"
#include "IceELFObjectWriter.h"
#include "PNaClTranslator.h"
#include "WasmTranslator.h"

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#endif // __clang__

#include "llvm/ADT/STLExtras.h"
#include "llvm/Bitcode/NaCl/NaClReaderWriter.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"

#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__

#include <regex>

namespace Ice {

namespace {

bool llvmIRInput(const std::string &Filename) {
  return BuildDefs::llvmIrAsInput() &&
         std::regex_match(Filename, std::regex(".*\\.ll"));
}

bool wasmInput(const std::string &Filename) {
  return BuildDefs::wasm() &&
         std::regex_match(Filename, std::regex(".*\\.wasm"));
}

} // end of anonymous namespace

void Compiler::run(const Ice::ClFlags &Flags, GlobalContext &Ctx,
                   std::unique_ptr<llvm::DataStreamer> &&InputStream) {
  // The Minimal build (specifically, when dump()/emit() are not implemented)
  // allows only --filetype=obj. Check here to avoid cryptic error messages
  // downstream.
  if (!BuildDefs::dump() && getFlags().getOutFileType() != FT_Elf) {
    Ctx.getStrError()
        << "Error: only --filetype=obj is supported in this build.\n";
    Ctx.getErrorStatus()->assign(EC_Args);
    return;
  }

  TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx);

  Ctx.emitFileHeader();
  Ctx.startWorkerThreads();

  std::unique_ptr<Translator> Translator;
  const std::string IRFilename = Flags.getIRFilename();
  const bool BuildOnRead = Flags.getBuildOnRead() && !llvmIRInput(IRFilename) &&
                           !wasmInput(IRFilename);
  const bool WasmBuildOnRead = Flags.getBuildOnRead() && wasmInput(IRFilename);
  if (BuildOnRead) {
    std::unique_ptr<PNaClTranslator> PTranslator(new PNaClTranslator(&Ctx));
#ifdef PNACL_LLVM
    std::unique_ptr<llvm::StreamingMemoryObject> MemObj(new llvm::StreamingMemoryObjectImpl(InputStream.release()));
#else // !PNACL_LLVM
    std::unique_ptr<llvm::StreamingMemoryObject> MemObj(new llvm::StreamingMemoryObject(std::move(InputStream)));
#endif // !PNACL_LLVM
    PTranslator->translate(IRFilename, std::move(MemObj));
    Translator.reset(PTranslator.release());
  } else if (WasmBuildOnRead) {
    if (BuildDefs::wasm()) {
#if !ALLOW_WASM
      assert(false && "wasm not allowed");
#else
      std::unique_ptr<WasmTranslator> WTranslator(new WasmTranslator(&Ctx));

      WTranslator->translate(IRFilename, std::move(InputStream));

      Translator.reset(WTranslator.release());
#endif // !ALLOW_WASM
    } else {
      Ctx.getStrError() << "WASM support not enabled\n";
      Ctx.getErrorStatus()->assign(EC_Args);
      return;
    }
  } else if (BuildDefs::llvmIr()) {
    if (BuildDefs::browser()) {
      Ctx.getStrError()
          << "non BuildOnRead is not supported w/ PNACL_BROWSER_TRANSLATOR\n";
      Ctx.getErrorStatus()->assign(EC_Args);
      Ctx.waitForWorkerThreads();
      return;
    }
    // Globals must be kept alive after lowering when converting from LLVM to
    // Ice.
    Ctx.setDisposeGlobalVariablesAfterLowering(false);
    // Parse the input LLVM IR file into a module.
    llvm::SMDiagnostic Err;
    TimerMarker T1(Ice::TimerStack::TT_parse, &Ctx);
#ifdef PNACL_LLVM
    llvm::DiagnosticHandlerFunction DiagnosticHandler =
        Flags.getLLVMVerboseErrors()
            ? redirectNaClDiagnosticToStream(llvm::errs())
            : nullptr;
    std::unique_ptr<llvm::Module> Mod =
        NaClParseIRFile(IRFilename, Flags.getInputFileFormat(), Err,
                        llvm::getGlobalContext(), DiagnosticHandler);
#else // !PNACL_LLVM
    llvm::DiagnosticHandlerFunction DiagnosticHandler = nullptr;
    llvm::LLVMContext Context;
    std::unique_ptr<llvm::Module> Mod =
        parseIRFile(IRFilename, Err, Context);
#endif // !PNACL_LLVM
    if (!Mod) {
      Err.print(Flags.getAppName().c_str(), llvm::errs());
      Ctx.getErrorStatus()->assign(EC_Bitcode);
      Ctx.waitForWorkerThreads();
      return;
    }

    std::unique_ptr<Converter> Converter(new class Converter(Mod.get(), &Ctx));
    Converter->convertToIce();
    Translator.reset(Converter.release());
  } else {
    Ctx.getStrError() << "Error: Build doesn't allow LLVM IR, "
                      << "--build-on-read=0 not allowed\n";
    Ctx.getErrorStatus()->assign(EC_Args);
    Ctx.waitForWorkerThreads();
    return;
  }

  Ctx.waitForWorkerThreads();
  if (Translator->getErrorStatus()) {
    Ctx.getErrorStatus()->assign(Translator->getErrorStatus().value());
  } else {
    Ctx.lowerGlobals("last");
    Ctx.lowerProfileData();
    Ctx.lowerConstants();
    Ctx.lowerJumpTables();

    if (getFlags().getOutFileType() == FT_Elf) {
      TimerMarker T1(Ice::TimerStack::TT_emitAsm, &Ctx);
      Ctx.getObjectWriter()->setUndefinedSyms(Ctx.getConstantExternSyms());
      Ctx.getObjectWriter()->writeNonUserSections();
    }
  }

  if (getFlags().getSubzeroTimingEnabled())
    Ctx.dumpTimers();

  if (getFlags().getTimeEachFunction()) {
    constexpr bool NoDumpCumulative = false;
    Ctx.dumpTimers(GlobalContext::TSK_Funcs, NoDumpCumulative);
  }
  Ctx.dumpStats();
}

} // end of namespace Ice
