//===-- llvm-goc.cpp - compiler driver for gollvm  ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Compiler driver for gollvm. Invokes frontend / backend to compile
// Go code into assembly and/or object files, and orchestrates process
// of assembling and linking if needed.
//
//===----------------------------------------------------------------------===//

#include "go-llvm-linemap.h"
#include "go-llvm-diagnostics.h"
#include "go-llvm.h"
#include "go-c.h"
#include "mpfr.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/CodeGen/CommandFlags.inc"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"

#include <algorithm>
#include <cstring>
#include <string>
#include <system_error>
#include <sys/types.h>
#include <unistd.h>

using namespace llvm;

static cl::opt<std::string>
TargetTriple("mtriple", cl::desc("Override target triple for module"));

static cl::list<std::string>
InputFilenames(cl::Positional,
               cl::desc("<input go source files>"),
               cl::OneOrMore);

static cl::list<std::string>
IncludeDirs("I", cl::desc("Include directory to be searched for packages."),
            cl::Prefix,
            cl::ZeroOrMore);

static cl::list<std::string>
LibDirs("L", cl::desc("Library directory to be added to search path"),
        cl::Prefix,
        cl::ZeroOrMore);

static cl::list<std::string>
PreprocDefs("D", cl::desc("Preprocessor definitions (currently ignored)."),
            cl::Prefix,
            cl::ZeroOrMore);

// Determine optimization level.
static cl::opt<char>
OptLevel("O",
         cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
                  "(default = '-O2')"),
         cl::Prefix,
         cl::ZeroOrMore,
         cl::init(' '));

static cl::opt<std::string>
OutputFileName("o",
               cl::desc("Set name of output file."),
               cl::init(""));

// These are provided for compatibility purposes -- they are currently ignored.
static cl::opt<bool>
M64Option("m64",  cl::desc("Dummy -m64 arg."), cl::init(false), cl::ZeroOrMore);
static cl::opt<bool>
MinusGOption("g",  cl::desc("Dummy -g arg."), cl::init(false), cl::ZeroOrMore);
static cl::opt<bool>
MinusCOption("c",  cl::desc("Dummy -c arg."), cl::init(false), cl::ZeroOrMore);
static cl::opt<bool>
MinusVOption("v",  cl::desc("Dummy -v arg."), cl::init(false), cl::ZeroOrMore);
static cl::opt<bool>
XasmCppOption("xassembler-with-cpp", cl::desc("Dummy -xassembler-with-cpp arg."), cl::init(false), cl::ZeroOrMore);


// Generate assembly and not object file. This is a no-op for now.
static cl::opt<bool>
CapSOption("S",  cl::desc("Emit assembly as opposed to object code."),
           cl::init(false), cl::ZeroOrMore);

static cl::opt<bool>
NoBackend("nobackend",
          cl::desc("Stub out back end invocation."),
          cl::init(false));

static cl::opt<bool>
NoVerify("noverify",
          cl::desc("Stub out module verifier invocation."),
          cl::init(false));

static cl::opt<bool>
CheckDivideZero("fgo-check-divide-zero",
                cl::desc("Add explicit checks for divide-by-zero."),
                cl::init(true));

static cl::opt<bool>
CheckDivideOverflow("fgo-check-divide-overflow",
                    cl::desc("Add explicit checks for division overflow in INT_MIN / -1."),
                    cl::init(true));

static cl::opt<bool>
CompilingRuntime("fgo-compiling-runtime",
                 cl::desc("Compiling the runtime package."),
                 cl::init(false));

static cl::opt<bool>
DumpAst("fgo-dump-ast",
        cl::desc("Dump Go frontend internal AST structure."),
        cl::init(false));

static cl::opt<bool>
DumpIR("dump-ir",
        cl::desc("Dump LLVM IR for module at end of run."),
        cl::init(false));

static cl::opt<bool>
NoInline("fno-inline",
         cl::desc("Disable inlining."),
         cl::init(false));

static cl::opt<bool>
OptimizeAllocs("fgo-optimize-allocs",
               cl::desc("Enable escape analysis in the go frontend."),
               cl::ZeroOrMore,
               cl::init(false));

static cl::opt<bool>
NoOptimizeAllocs("fno-go-optimize-allocs",
               cl::desc("Disable escape analysis in the go frontend."),
               cl::ZeroOrMore,
               cl::init(false));

static cl::opt<std::string>
PackagePath("fgo-pkgpath",
            cl::desc("Set Go package path."),
            cl::init(""));

static cl::opt<std::string>
PackagePrefix("fgo-prefix",
              cl::desc("Set package-specific prefix for exported Go names."),
              cl::init(""));

static cl::opt<std::string>
RelativeImportPath("fgo-relative-import-path",
                   cl::desc("Treat a relative import as relative to path."),
                   cl::init(""));

static cl::opt<std::string>
CHeader("fgo-c-header",
        cl::desc("The C header file to write."),
        cl::init(""));

static cl::opt<int>
EscapeDebugLevel("fgo-debug-escape",
                 cl::desc("Emit debugging information related to the "
                          "escape analysis pass when run with "
                          "-fgo-optimize-allocs."),
                 cl::init(0));

static cl::opt<std::string>
EscapeDebugHash("fgo-debug-escape-hash",
        cl::desc("A hash value to debug escape analysis. Argument is "
                 "a binary string. This runs escape analysis only on "
                 "functions whose names hash to values that match the "
                 "given suffix. Can be used to binary search across "
                 "functions to uncover escape analysis bugs."),
                cl::init(""));

static cl::opt<unsigned>
TraceLevel("tracelevel",
           cl::desc("Set debug trace level (def: 0, no trace output)."),
           cl::init(0));

// Provide a way to turn off the full passmanager (to make it easier
// to triage failures). This should be a temporary flag (not for the
// long term).
static cl::opt<bool>
FullPasses("full-passes",
           cl::desc("Enable all available optimization passes."),
           cl::init(true));

static cl::alias
FFuseFPOps("ffp-contract",
           cl::desc("Alias for -fp-contract"),
           cl::aliasopt(FuseFPOps));

static cl::opt<bool>
NoTrappingMath("fno-trapping-math",
               cl::desc("Generate code with the assumption FP operations will "
                        "not generate user-visible traps."),
               cl::ZeroOrMore,
               cl::init(false));

static cl::opt<bool>
TrappingMath("ftrapping-math",
             cl::desc("Generate code with the assumption FP operations can "
                      "generate user-visible traps."),
             cl::ZeroOrMore,
             cl::init(false));

static cl::opt<bool>
NoMathErrno("fno-math-errno",
            cl::desc("Do not require that math functions set "
                     "'errno' to indicate errors. This option has no "
                     "effect (provided for compatibility purposes)."),
            cl::ZeroOrMore,
            cl::init(false));

static cl::opt<bool>
MathErrno("fmath-errno",
          cl::desc("Insure that calls to math functions that incur errors "
                   "results in setting of 'errno' (unimplemented, will "
                   "generate an error if not overridden with a subsequent "
                   "instance of -fno-math-errno)."),
          cl::ZeroOrMore,
          cl::init(false));

// Given a pair of cl::opt objects corresponding to -fXXX and -fno-XXX
// boolean flags, select the correct value for the option depending on
// the relative position of the options on the command line (rightmost
// wins). For example, given -fblah -fno-blah -fblah, we want the same
// semantics as a single -fblah.

static bool reconcileOptionPair(cl::opt<bool> &yesOption,
                                cl::opt<bool> &noOption,
                                bool defaultVal)
{
  bool value = defaultVal;
  if (yesOption.getNumOccurrences() > 0) {
    if (noOption.getNumOccurrences() > 0) {
      value = yesOption.getPosition() > noOption.getPosition();
    } else {
      value = true;
    }
  } else {
    if (noOption.getNumOccurrences() > 0) {
      value = false;
    }
  }
  return value;
}

static cl::opt<bool>
PICSmall("fpic",
        cl::desc("Generate position-independent code (small model)."),
        cl::ZeroOrMore,
        cl::init(false));

static cl::opt<bool>
PICBig("fPIC",
        cl::desc("Generate position-independent code (large model)."),
        cl::ZeroOrMore,
        cl::init(false));

// Return any settings from the -fPIC/-fpic options, if present. The
// intent of the code below is to support "rightmost on the command
// line wins" (compatible with clang and other compilers), so if you
// specify "-fPIC -fpic" you get small PIC, whereas "-fPIC -fpic
// -fPIC" this will give you large PIC.
static PICLevel::Level getPicLevel()
{
  auto picLevel = PICLevel::NotPIC;
  if (PICBig && PICSmall.getPosition() < PICBig.getPosition())
    picLevel = PICLevel::BigPIC;
  else if (PICSmall && PICSmall.getPosition() > PICBig.getPosition())
    picLevel = PICLevel::SmallPIC;
  return picLevel;
}

static PICLevel::Level reconcilePicLevel()
{
  // FIXME: as a result of including CodeGen/CommandFlags.def, we have
  // both the -relocation-model option as well as -fpic/-fPIC. For
  // now, honor the former first, then the latter (this behavior will
  // eventually go away once we no longer use CommandFlags.def).
  if (RelocModel.getNumOccurrences() > 0) {
    if (RelocModel == llvm::Reloc::Static)
      return llvm::PICLevel::NotPIC;
    assert(RelocModel == llvm::Reloc::PIC_);
    return llvm::PICLevel::BigPIC;
  }
  return getPicLevel();
}

static llvm::Optional<llvm::Reloc::Model> reconcileRelocModel()
{
  // FIXME: again, as a result of including CodeGen/CommandFlags.def,
  // both the -relocation-model option as well as -fpic/-fPIC.  Honor
  // the first the former, then the latter.
  if (RelocModel.getNumOccurrences()) {
    llvm::Reloc::Model R = RelocModel;
    return R;
  }
  auto picLevel = getPicLevel();
  if (picLevel != llvm::PICLevel::NotPIC) {
    Reloc::Model R = Reloc::PIC_;
    return R;
  }
  return None;
}

static TargetMachine::CodeGenFileType getOutputFileType()
{
  // FIXME: as a result of including CodeGen/CommandFlags.def, we have
  // both the -filetype option as well as "-S". For now, honor the
  // former first, then the latter (eventually we'll want to move away
  // from CommandFlags.def).
  TargetMachine::CodeGenFileType ft;
  if (FileType.getNumOccurrences() > 0)
    ft = FileType;
  else if (CapSOption.getNumOccurrences() > 0 && CapSOption)
    ft = TargetMachine::CGFT_AssemblyFile;
  else
    ft = TargetMachine::CGFT_ObjectFile;
  return ft;
}

static std::unique_ptr<ToolOutputFile>
GetOutputStream(std::string outFileName, bool binary)
{
  // Open the file.
  std::error_code EC;
  sys::fs::OpenFlags OpenFlags = sys::fs::F_None;
  if (!binary)
    OpenFlags |= sys::fs::F_Text;
  auto FDOut = llvm::make_unique<ToolOutputFile>(outFileName, EC,
                                                OpenFlags);
  if (EC) {
    errs() << "error opening " << outFileName << ": "
           << EC.message() << '\n';
    return nullptr;
  }

  return FDOut;
}

class BEDiagnosticHandler : public DiagnosticHandler {
  bool *error_;
 public:
  BEDiagnosticHandler(bool *errorPtr)
      : error_(errorPtr) {}
  bool handleDiagnostics(const DiagnosticInfo &DI) override {
    if (DI.getSeverity() == DS_Error)
      *error_ = true;
    if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
      if (!Remark->isEnabled())
        return true;
    DiagnosticPrinterRawOStream DP(errs());
    errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
    DI.print(DP);
    errs() << "\n";
    return true;
  }
};

// Are we in "assemble" mode (all inputs are .s files) or "compile" mode
// (all inputs are *.go files)?
enum CompileMode {
  UnknownCompileMode,
  CompileAssemblyMode,
  CompileGoMode
};

// Helper class for managing the overall Go compilation process.

class CompilationOrchestrator {
 public:
  CompilationOrchestrator(const char *argvZero);
  ~CompilationOrchestrator();

  // Various stages in the setup/execution of the compilation.  The
  // convention here is to return false if there was a fatal error, true
  // otherwise.
  bool preamble();
  bool initBridge();
  bool resolveInputOutput();
  bool invokeFrontEnd();
  bool invokeBridge();
  bool invokeBackEnd();
  bool invokeAssembler();

 private:
  Triple triple_;
  llvm::LLVMContext context_;
  const char *progname_;
  CodeGenOpt::Level cgolvl_;
  unsigned olvl_;
  std::unique_ptr<Llvm_backend> bridge_;
  std::unique_ptr<TargetMachine> target_;
  std::unique_ptr<Llvm_linemap> linemap_;
  std::unique_ptr<llvm::Module> module_;
  std::string outFileName_;
  std::string asmOutFileName_;
  std::unique_ptr<ToolOutputFile> asmout_;
  std::unique_ptr<ToolOutputFile> out_;
  std::unique_ptr<TargetLibraryInfoImpl> tlii_;
  CompileMode compileMode_;
  bool hasError_;
  bool tmpCreated_;

  CompileMode compileMode() const { return compileMode_; }
  bool setCompileMode(CompileMode mode) {
    bool mixedModeError = false;
    if (compileMode_ == UnknownCompileMode)
      compileMode_ = mode;
    else if (compileMode_ != mode)
      mixedModeError = true;
    return mixedModeError;
  }

  void createPasses(legacy::PassManager &MPM,
                    legacy::FunctionPassManager &FPM);
};

CompilationOrchestrator::CompilationOrchestrator(const char *argvZero)

    : progname_(argvZero), cgolvl_(CodeGenOpt::Default),
      olvl_(2), compileMode_(UnknownCompileMode),
      hasError_(false), tmpCreated_(false)
{
  InitializeAllTargets();
  InitializeAllTargetMCs();
  InitializeAllAsmPrinters();
  InitializeAllAsmParsers();
}

CompilationOrchestrator::~CompilationOrchestrator()
{
  if (tmpCreated_)
    sys::fs::remove(asmOutFileName_);
}

bool CompilationOrchestrator::preamble()
{
  triple_ = Triple(Triple::normalize(TargetTriple));
  if (triple_.getTriple().empty())
    triple_.setTriple(sys::getDefaultTargetTriple());

  // Get the target specific parser.
  std::string Error;
  const Target *TheTarget =
      TargetRegistry::lookupTarget(MArch, triple_, Error);
  if (!TheTarget) {
    errs() << progname_ << ": " << Error;
    return false;
  }

  // FIXME: cpu, features not yet supported
  std::string CPUStr = getCPUStr(), FeaturesStr = getFeaturesStr();

  // optimization level
  switch (OptLevel) {
    default:
      errs() << progname_ << ": invalid optimization level.\n";
      return false;
    case '0':
      olvl_ = 0;
      cgolvl_ = CodeGenOpt::None;
      break;
    case '1':
      olvl_ = 1;
      cgolvl_ = CodeGenOpt::Less;
      break;
    case 's': // TODO: same as -O2 for now.
    case ' ':
    case '2':
      break;
    case '3':
      olvl_ = 3;
      cgolvl_ = CodeGenOpt::Aggressive;
      break;
  }

  go_no_warn = NoWarn;

  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();

  // FIXME: turn off integrated assembler for now.
  Options.DisableIntegratedAS = true;

  // FIXME: this hard-wires on the equivalent of -ffunction-sections
  // and -fdata-sections, since there doesn't seem to be a high-level
  // hook for selecting a separate section for a specific variable or
  // function (other than forcing it into a comdat, which is not
  // always what we want).
  Options.FunctionSections = true;
  Options.DataSections = true;

  // FP trapping mode
  Options.NoTrappingFPMath = !reconcileOptionPair(TrappingMath,
                                                  NoTrappingMath,
                                                  true);

  // The -fno-math-errno option is essentially a no-op when compiling
  // Go code, but -fmath-errno does not make sense, since 'errno' is
  // not exposed in any meaningful way as part of the math package.
  // Allow users to set -fno-math-errno for compatibility reasons, but
  // issue an error if -fmath-errno is set.
  bool mathErrno = reconcileOptionPair(MathErrno, NoMathErrno, false);
  if (mathErrno) {
    errs() << "error: -fmath-errno unsupported for Go code\n";
    return false;
  }

  // FP contract settings.
  Options.AllowFPOpFusion = FuseFPOps;

  // FIXME: get rid of -fp-contract in favor of -ffp-contract
  // FIXME: allow multiple -ffp-contract=XXX settings on the command line.

  // Create target machine
  Optional<llvm::CodeModel::Model> CM = None;
  target_.reset(
      TheTarget->createTargetMachine(triple_.getTriple(), CPUStr, FeaturesStr,
                                     Options, reconcileRelocModel(),
                                     CM, cgolvl_));
  assert(target_.get() && "Could not allocate target machine!");

  return true;
}

// This helper performs the various initial steps needed to set up the
// compilation, including prepping the LLVM context, creating an LLVM
// module, creating the bridge itself (Llvm_backend object) and
// setting up the Go frontend via a call to go_create_gogo(). At the
// end of this routine things should be ready to kick off the front end.

bool CompilationOrchestrator::initBridge()
{
  // Set up the LLVM context
  context_.setDiagnosticHandler(
      llvm::make_unique<BEDiagnosticHandler>(&this->hasError_));

  // Vett relocation model.
  if (RelocModel.getNumOccurrences() > 0 &&
      (RelocModel != llvm::Reloc::Static &&
       RelocModel != llvm::Reloc::PIC_)) {
    errs() << "error: unsupported -relocation-model selection\n";
    return false;
  }

  // Construct linemap and module
  linemap_.reset(new Llvm_linemap());
  module_.reset(new llvm::Module("gomodule", context_));

  // Add the target data from the target machine, if it exists
  module_->setTargetTriple(triple_.getTriple());
  module_->setDataLayout(target_->createDataLayout());
  module_->setPICLevel(reconcilePicLevel());

  // Now construct Llvm_backend helper.
  bridge_.reset(new Llvm_backend(context_, module_.get(), linemap_.get()));

  // Honor inline, tracelevel cmd line options
  bridge_->setTraceLevel(TraceLevel);
  bridge_->setNoInline(NoInline);

  // Support -fgo-dump-ast
  if (DumpAst)
    go_enable_dump("ast");

  // Populate 'args' struct with various bits of information needed by
  // the front end, then pass it to the front end via go_create_gogo().
  struct go_create_gogo_args args;
  unsigned bpi = target_->getPointerSize(0) * 8;
  args.int_type_size = bpi;
  args.pointer_size = bpi;
  args.pkgpath = PackagePath.empty() ? NULL : PackagePath.c_str();
  args.prefix = PackagePrefix.empty() ? NULL : PackagePrefix.c_str();
  args.relative_import_path =
      RelativeImportPath.empty() ? NULL : RelativeImportPath.c_str();
  args.c_header = CHeader.empty() ? NULL : CHeader.c_str();
  args.check_divide_by_zero = CheckDivideZero;
  args.check_divide_overflow = CheckDivideOverflow;
  args.compiling_runtime = CompilingRuntime;
  args.debug_escape_level = EscapeDebugLevel;
  args.debug_escape_hash = nullptr;
  if (!EscapeDebugHash.empty())
    args.debug_escape_hash = EscapeDebugHash.c_str();
  args.nil_check_size_threshold = -1;
  args.linemap = linemap_.get();
  args.backend = bridge_.get();
  go_create_gogo (&args);

  /* The default precision for floating point numbers.  This is used
     for floating point constants with abstract type.  This may
     eventually be controllable by a command line option.  */
  mpfr_set_default_prec (256);

  // Escape analysis
  bool enableEscapeAnalysis = reconcileOptionPair(OptimizeAllocs,
                                                  NoOptimizeAllocs,
                                                  true);
  go_enable_optimize("allocs", enableEscapeAnalysis ? 1 : 0);

  // Include dirs
  if (! IncludeDirs.empty()) {
    for (auto dir : IncludeDirs) {
      if (sys::fs::is_directory(dir))
        go_add_search_path(dir.c_str());
    }
  }

  // Library dirs
  // TODO: add version, architecture dirs
  if (! LibDirs.empty()) {
    for (auto dir : LibDirs) {
      struct stat st;
      if (stat (dir.c_str(), &st) == 0 && S_ISDIR (st.st_mode))
        go_add_search_path(dir.c_str());
    }
  }

  return true;
}

bool CompilationOrchestrator::resolveInputOutput()
{
  // What 'mode' are we operating in? If all inputs are *.s files,
  // then we're in assemble mode; if all inputs are *.go files, we're
  // in compile mode. No support for a mix of *.s and *.go files.
  bool mixedModeError = false;
  if (InputFilenames.size() == 0) {
    errs() << "error: no input files supplied.\n";
    return false;
  }
  for (auto &fn : InputFilenames) {
    // Check for existence of input file.
    if (!sys::fs::exists(fn)) {
      errs() << "error: input file '"
             << fn << "' does not exist\n";
      return false;
    }
    size_t dotindex = fn.find_last_of(".");
    if (dotindex == std::string::npos) {
      errs() << "error: malformed input file '"
             << fn << "' (no extension)\n";
      return false;
    }
    std::string extension = fn.substr(dotindex);
    if (extension.compare(".s") == 0) {
      mixedModeError = setCompileMode(CompileAssemblyMode);
      if (mixedModeError)
        break;
    } else if (extension.compare(".go") == 0) {
      mixedModeError = setCompileMode(CompileGoMode);
      if (mixedModeError)
        break;
    } else {
      errs() << "error: unknown input file '"
             << fn << "' (extension must be '.s' or '.go')\n";
      return false;
    }
  }
  if (mixedModeError) {
    errs() << "error: mixing of assembler (*.s) and Go (*.go) "
           << "source files not supported.\n";
    return false;
  }
  if (CapSOption && compileMode_ == CompileAssemblyMode) {
    errs() << "error: -S option not valid if input files "
           << "are assembly source.\n";
    return false;
  }

  // Decide where we're going to send the output for this compilation.
  // If the "-o" option was not specified, use the basename of the
  // first input argument.
  outFileName_ = OutputFileName;
  TargetMachine::CodeGenFileType ft = getOutputFileType();
  if (OutputFileName.empty()) {
    std::string firstFile = InputFilenames[0];
    size_t dotindex = firstFile.find_last_of(".");
    assert(dotindex != std::string::npos);
    outFileName_ = firstFile.substr(0, dotindex);
    outFileName_ += (ft == TargetMachine::CGFT_AssemblyFile ? ".s" : ".o");
  }

  // If we're not compiling to assembly, then we need an intermediate
  // output file into which we'll emit assembly code.
  if (ft != TargetMachine::CGFT_AssemblyFile) {
    llvm::SmallString<128> tempFileName;
    std::error_code tfcEC =
        llvm::sys::fs::createTemporaryFile("asm", "s", tempFileName);
    if (tfcEC) {
      errs() << tfcEC.message() << "\n";
      return false;
    }
    tmpCreated_ = true;
    sys::RemoveFileOnSignal(tempFileName);
    asmOutFileName_ = std::string(tempFileName.c_str());
  } else {
    asmOutFileName_ = outFileName_;
  }

  // Open the assembler output file
  asmout_ = GetOutputStream(asmOutFileName_, /*text*/ false);
  if (!asmout_)
    return false;

  // Open object file as well if needed
  if (ft != TargetMachine::CGFT_AssemblyFile) {
    out_ = GetOutputStream(outFileName_, /*binary*/ true);
    if (!out_)
      return false;
  }

  return true;
}

bool CompilationOrchestrator::invokeFrontEnd()
{
  // If we're in "assemble" mode, no need to invoke the compiler
  if (compileMode_ == CompileAssemblyMode)
    return true;

  // Collect the input files and kick off the front end
  // Kick off the front end
  unsigned nfiles = InputFilenames.size();
  std::unique_ptr<const char *> filenames(new const char *[nfiles]);
  const char **fns = filenames.get();
  unsigned idx = 0;
  for (auto &fn : InputFilenames)
    fns[idx++] = fn.c_str();
  go_parse_input_files(fns, nfiles, false, true);
  if (! NoBackend)
    go_write_globals();
  if (DumpIR)
    bridge_->dumpModule();
  if (! NoVerify && !go_be_saw_errors())
    bridge_->verifyModule();
  if (TraceLevel)
    std::cerr << "linemap stats:" << linemap_->statistics() << "\n";

  // Delete the bridge at this point. In the case that there were
  // errors, this will help clean up any unreachable llvm Instructions
  // (which would otherwise trigger asserts); in the non-error case it
  // will help to free up bridge-related memory prior to kicking off
  // the pass manager.
  bridge_.reset(nullptr);

  // Early exit at this point if we've seen errors
  if (go_be_saw_errors())
    return false;

  return true;
}

void CompilationOrchestrator::createPasses(legacy::PassManager &MPM,
                                           legacy::FunctionPassManager &FPM)
{
  // FIXME: support LTO, ThinLTO, PGO

  PassManagerBuilder pmb;

  // Configure the inliner
  if (NoInline || olvl_ == 0) {
    // Nothing here at the moment. There is go:noinline, but no equivalent
    // of go:alwaysinline.
  } else {
    bool disableInlineHotCallSite = false; // for autofdo, not yet supported
    pmb.Inliner =
        createFunctionInliningPass(olvl_, 2, disableInlineHotCallSite);
  }

  pmb.OptLevel = olvl_;
  pmb.SizeLevel = 0; // TODO: decide on right value here
  pmb.PrepareForThinLTO = false;
  pmb.PrepareForLTO = false;

  FPM.add(new TargetLibraryInfoWrapperPass(*tlii_));
  if (! NoVerify)
    FPM.add(createVerifierPass());

  pmb.populateFunctionPassManager(FPM);
  pmb.populateModulePassManager(MPM);
}

bool CompilationOrchestrator::invokeBackEnd()
{
  // If we're in "assemble" mode, no need to invoke the compiler
  if (compileMode_ == CompileAssemblyMode)
    return true;

  tlii_.reset(new TargetLibraryInfoImpl(triple_));

  // Set up module and function passes
  legacy::PassManager modulePasses;
  modulePasses.add(
      createTargetTransformInfoWrapperPass(target_->getTargetIRAnalysis()));
  legacy::FunctionPassManager functionPasses(module_.get());
  functionPasses.add(
      createTargetTransformInfoWrapperPass(target_->getTargetIRAnalysis()));
  createPasses(modulePasses, functionPasses);

  // Set up codegen passes
  legacy::PassManager codeGenPasses;
  codeGenPasses.add(
      createTargetTransformInfoWrapperPass(target_->getTargetIRAnalysis()));

  // Codegen setup
  raw_pwrite_stream *OS = &asmout_->os();
  codeGenPasses.add(new TargetLibraryInfoWrapperPass(*tlii_));
  if (target_->addPassesToEmitFile(codeGenPasses, *OS, FileType,
                                   /*DisableVerify=*/ NoVerify)) {
    errs() << "error: unable to interface with target\n";
    return false;
  }

  // Before executing passes, print the final values of the LLVM options.
  cl::PrintOptionValues();

  // Temporary -- to be removed in a follow-on CL
  if (FullPasses) {

    // Here we go... first function passes
    functionPasses.doInitialization();
    for (Function &F : *module_.get())
      if (!F.isDeclaration())
        functionPasses.run(F);
    functionPasses.doFinalization();

    // ... then module passes
    modulePasses.run(*module_.get());
  }

  // ... and finally code generation
  codeGenPasses.run(*module_.get());

  if (hasError_)
    return false;

  // Keep the resulting output file if -S is in effect.
  if (getOutputFileType() == TargetMachine::CGFT_AssemblyFile)
    asmout_->keep();

  return true;
}

bool CompilationOrchestrator::invokeAssembler()
{
  if (getOutputFileType() == TargetMachine::CGFT_AssemblyFile)
    return true;

  ArrayRef<StringRef> searchpaths;
  auto aspath = sys::findProgramByName("as", searchpaths);
  if (! aspath ) {
    errs() << "error: unable to locate path for 'as'" << "\n";
    return false;
  }

  std::vector<const char *> args;
  args.push_back("as");
  if (compileMode_ == CompileAssemblyMode) {
    for (auto &fn : InputFilenames)
      args.push_back(fn.c_str());
  } else {
    args.push_back(asmOutFileName_.c_str());
  }
  args.push_back("-o");
  args.push_back(outFileName_.c_str());
  args.push_back(nullptr);

  std::string errMsg;
  bool rval = true;
  int rc = sys::ExecuteAndWait(*aspath, args.data(),
                               /*env=*/nullptr, /*Redirects*/{},
                               /*secondsToWait=*/0,
                               /*memoryLimit=*/0, &errMsg);
  if (rc != 0) {
    errs() << errMsg << "\n";
    rval = false;
  } else {
    out_->keep();
  }

  return rval;
}

int main(int argc, char **argv)
{
  CompilationOrchestrator orchestrator(argv[0]);

  cl::ParseCommandLineOptions(argc, argv, "gollvm driver\n");

  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal(argv[0]);
  PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  // Initialize target and sort out selected command line options.
  if (!orchestrator.preamble())
    return 1;

  // Set up the bridge
  if (!orchestrator.initBridge())
    return 2;

  // Determine output file
  if (!orchestrator.resolveInputOutput())
    return 3;

  // Invoke front end
  if (! orchestrator.invokeFrontEnd())
    return 4;

  // Invoke back end
  if (! orchestrator.invokeBackEnd())
    return 5;

  // Invoke assembler if needed.
  if (! orchestrator.invokeAssembler())
    return 6;

  // We're done.
  return 0;
}
