//===- llvm-lto: a simple command-line program to link modules with LTO ---===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This program takes in a list of bitcode files, links them, performs link-time
// optimization, and outputs an object file.
//
//===----------------------------------------------------------------------===//

#include "llvm-c/lto.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/LTO/legacy/LTOCodeGenerator.h"
#include "llvm/LTO/legacy/LTOModule.h"
#include "llvm/LTO/legacy/ThinLTOCodeGenerator.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Target/TargetOptions.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <map>
#include <memory>
#include <string>
#include <system_error>
#include <tuple>
#include <utility>
#include <vector>

using namespace llvm;

static codegen::RegisterCodeGenFlags CGF;

static cl::OptionCategory LTOCategory("LTO Options");

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

static cl::opt<bool>
    IndexStats("thinlto-index-stats",
               cl::desc("Print statistic for the index in every input files"),
               cl::init(false), cl::cat(LTOCategory));

static cl::opt<bool> DisableVerify(
    "disable-verify", cl::init(false),
    cl::desc("Do not run the verifier during the optimization pipeline"),
    cl::cat(LTOCategory));

static cl::opt<bool> EnableFreestanding(
    "lto-freestanding", cl::init(false),
    cl::desc("Enable Freestanding (disable builtins / TLI) during LTO"),
    cl::cat(LTOCategory));

static cl::opt<bool> UseDiagnosticHandler(
    "use-diagnostic-handler", cl::init(false),
    cl::desc("Use a diagnostic handler to test the handler interface"),
    cl::cat(LTOCategory));

static cl::opt<bool>
    ThinLTO("thinlto", cl::init(false),
            cl::desc("Only write combined global index for ThinLTO backends"),
            cl::cat(LTOCategory));

enum ThinLTOModes {
  THINLINK,
  THINDISTRIBUTE,
  THINEMITIMPORTS,
  THINPROMOTE,
  THINIMPORT,
  THININTERNALIZE,
  THINOPT,
  THINCODEGEN,
  THINALL
};

static cl::opt<ThinLTOModes> ThinLTOMode(
    "thinlto-action", cl::desc("Perform a single ThinLTO stage:"),
    cl::values(
        clEnumValN(
            THINLINK, "thinlink",
            "ThinLink: produces the index by linking only the summaries."),
        clEnumValN(THINDISTRIBUTE, "distributedindexes",
                   "Produces individual indexes for distributed backends."),
        clEnumValN(THINEMITIMPORTS, "emitimports",
                   "Emit imports files for distributed backends."),
        clEnumValN(THINPROMOTE, "promote",
                   "Perform pre-import promotion (requires -thinlto-index)."),
        clEnumValN(THINIMPORT, "import",
                   "Perform both promotion and "
                   "cross-module importing (requires "
                   "-thinlto-index)."),
        clEnumValN(THININTERNALIZE, "internalize",
                   "Perform internalization driven by -exported-symbol "
                   "(requires -thinlto-index)."),
        clEnumValN(THINOPT, "optimize", "Perform ThinLTO optimizations."),
        clEnumValN(THINCODEGEN, "codegen", "CodeGen (expected to match llc)"),
        clEnumValN(THINALL, "run", "Perform ThinLTO end-to-end")),
    cl::cat(LTOCategory));

static cl::opt<std::string>
    ThinLTOIndex("thinlto-index",
                 cl::desc("Provide the index produced by a ThinLink, required "
                          "to perform the promotion and/or importing."),
                 cl::cat(LTOCategory));

static cl::opt<std::string> ThinLTOPrefixReplace(
    "thinlto-prefix-replace",
    cl::desc("Control where files for distributed backends are "
             "created. Expects 'oldprefix;newprefix' and if path "
             "prefix of output file is oldprefix it will be "
             "replaced with newprefix."),
    cl::cat(LTOCategory));

static cl::opt<std::string> ThinLTOModuleId(
    "thinlto-module-id",
    cl::desc("For the module ID for the file to process, useful to "
             "match what is in the index."),
    cl::cat(LTOCategory));

static cl::opt<std::string> ThinLTOCacheDir("thinlto-cache-dir",
                                            cl::desc("Enable ThinLTO caching."),
                                            cl::cat(LTOCategory));

static cl::opt<int> ThinLTOCachePruningInterval(
    "thinlto-cache-pruning-interval", cl::init(1200),
    cl::desc("Set ThinLTO cache pruning interval."), cl::cat(LTOCategory));

static cl::opt<uint64_t> ThinLTOCacheMaxSizeBytes(
    "thinlto-cache-max-size-bytes",
    cl::desc("Set ThinLTO cache pruning directory maximum size in bytes."),
    cl::cat(LTOCategory));

static cl::opt<int> ThinLTOCacheMaxSizeFiles(
    "thinlto-cache-max-size-files", cl::init(1000000),
    cl::desc("Set ThinLTO cache pruning directory maximum number of files."),
    cl::cat(LTOCategory));

static cl::opt<unsigned> ThinLTOCacheEntryExpiration(
    "thinlto-cache-entry-expiration", cl::init(604800) /* 1w */,
    cl::desc("Set ThinLTO cache entry expiration time."), cl::cat(LTOCategory));

static cl::opt<std::string> ThinLTOSaveTempsPrefix(
    "thinlto-save-temps",
    cl::desc("Save ThinLTO temp files using filenames created by adding "
             "suffixes to the given file path prefix."),
    cl::cat(LTOCategory));

static cl::opt<std::string> ThinLTOGeneratedObjectsDir(
    "thinlto-save-objects",
    cl::desc("Save ThinLTO generated object files using filenames created in "
             "the given directory."),
    cl::cat(LTOCategory));

static cl::opt<bool> SaveLinkedModuleFile(
    "save-linked-module", cl::init(false),
    cl::desc("Write linked LTO module to file before optimize"),
    cl::cat(LTOCategory));

static cl::opt<bool>
    SaveModuleFile("save-merged-module", cl::init(false),
                   cl::desc("Write merged LTO module to file before CodeGen"),
                   cl::cat(LTOCategory));

static cl::list<std::string> InputFilenames(cl::Positional, cl::OneOrMore,
                                            cl::desc("<input bitcode files>"),
                                            cl::cat(LTOCategory));

static cl::opt<std::string> OutputFilename("o", cl::init(""),
                                           cl::desc("Override output filename"),
                                           cl::value_desc("filename"),
                                           cl::cat(LTOCategory));

static cl::list<std::string> ExportedSymbols(
    "exported-symbol",
    cl::desc("List of symbols to export from the resulting object file"),
    cl::cat(LTOCategory));

static cl::list<std::string>
    DSOSymbols("dso-symbol",
               cl::desc("Symbol to put in the symtab in the resulting dso"),
               cl::cat(LTOCategory));

static cl::opt<bool> ListSymbolsOnly(
    "list-symbols-only", cl::init(false),
    cl::desc("Instead of running LTO, list the symbols in each IR file"),
    cl::cat(LTOCategory));

static cl::opt<bool> ListDependentLibrariesOnly(
    "list-dependent-libraries-only", cl::init(false),
    cl::desc(
        "Instead of running LTO, list the dependent libraries in each IR file"),
    cl::cat(LTOCategory));

static cl::opt<bool> QueryHasCtorDtor(
    "query-hasCtorDtor", cl::init(false),
    cl::desc("Queries LTOModule::hasCtorDtor() on each IR file"));

static cl::opt<bool>
    SetMergedModule("set-merged-module", cl::init(false),
                    cl::desc("Use the first input module as the merged module"),
                    cl::cat(LTOCategory));

static cl::opt<unsigned> Parallelism("j", cl::Prefix, cl::init(1),
                                     cl::desc("Number of backend threads"),
                                     cl::cat(LTOCategory));

static cl::opt<bool> RestoreGlobalsLinkage(
    "restore-linkage", cl::init(false),
    cl::desc("Restore original linkage of globals prior to CodeGen"),
    cl::cat(LTOCategory));

static cl::opt<bool> CheckHasObjC(
    "check-for-objc", cl::init(false),
    cl::desc("Only check if the module has objective-C defined in it"),
    cl::cat(LTOCategory));

static cl::opt<bool> PrintMachOCPUOnly(
    "print-macho-cpu-only", cl::init(false),
    cl::desc("Instead of running LTO, print the mach-o cpu in each IR file"),
    cl::cat(LTOCategory));

static cl::opt<bool>
    DebugPassManager("debug-pass-manager", cl::init(false), cl::Hidden,
                     cl::desc("Print pass management debugging information"),
                     cl::cat(LTOCategory));

static cl::opt<bool>
    LTOSaveBeforeOpt("lto-save-before-opt", cl::init(false),
                     cl::desc("Save the IR before running optimizations"));

namespace {

struct ModuleInfo {
  BitVector CanBeHidden;
};

} // end anonymous namespace

static void handleDiagnostics(lto_codegen_diagnostic_severity_t Severity,
                              const char *Msg, void *) {
  errs() << "llvm-lto: ";
  switch (Severity) {
  case LTO_DS_NOTE:
    errs() << "note: ";
    break;
  case LTO_DS_REMARK:
    errs() << "remark: ";
    break;
  case LTO_DS_ERROR:
    errs() << "error: ";
    break;
  case LTO_DS_WARNING:
    errs() << "warning: ";
    break;
  }
  errs() << Msg << "\n";
}

static std::string CurrentActivity;

namespace {
  struct LLVMLTODiagnosticHandler : public DiagnosticHandler {
    bool handleDiagnostics(const DiagnosticInfo &DI) override {
      raw_ostream &OS = errs();
      OS << "llvm-lto: ";
      switch (DI.getSeverity()) {
      case DS_Error:
        OS << "error";
        break;
      case DS_Warning:
        OS << "warning";
        break;
      case DS_Remark:
        OS << "remark";
        break;
      case DS_Note:
        OS << "note";
        break;
      }
      if (!CurrentActivity.empty())
        OS << ' ' << CurrentActivity;
      OS << ": ";

      DiagnosticPrinterRawOStream DP(OS);
      DI.print(DP);
      OS << '\n';

      if (DI.getSeverity() == DS_Error)
        exit(1);
      return true;
    }
  };
  }

static void error(const Twine &Msg) {
  errs() << "llvm-lto: " << Msg << '\n';
  exit(1);
}

static void error(std::error_code EC, const Twine &Prefix) {
  if (EC)
    error(Prefix + ": " + EC.message());
}

template <typename T>
static void error(const ErrorOr<T> &V, const Twine &Prefix) {
  error(V.getError(), Prefix);
}

static void maybeVerifyModule(const Module &Mod) {
  if (!DisableVerify && verifyModule(Mod, &errs()))
    error("Broken Module");
}

static std::unique_ptr<LTOModule>
getLocalLTOModule(StringRef Path, std::unique_ptr<MemoryBuffer> &Buffer,
                  const TargetOptions &Options) {
  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
      MemoryBuffer::getFile(Path);
  error(BufferOrErr, "error loading file '" + Path + "'");
  Buffer = std::move(BufferOrErr.get());
  CurrentActivity = ("loading file '" + Path + "'").str();
  std::unique_ptr<LLVMContext> Context = std::make_unique<LLVMContext>();
  Context->setDiagnosticHandler(std::make_unique<LLVMLTODiagnosticHandler>(),
                                true);
  ErrorOr<std::unique_ptr<LTOModule>> Ret = LTOModule::createInLocalContext(
      std::move(Context), Buffer->getBufferStart(), Buffer->getBufferSize(),
      Options, Path);
  CurrentActivity = "";
  maybeVerifyModule((*Ret)->getModule());
  return std::move(*Ret);
}

/// Print some statistics on the index for each input files.
static void printIndexStats() {
  for (auto &Filename : InputFilenames) {
    ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename + "': ");
    std::unique_ptr<ModuleSummaryIndex> Index =
        ExitOnErr(getModuleSummaryIndexForFile(Filename));
    // Skip files without a module summary.
    if (!Index)
      report_fatal_error(Twine(Filename) + " does not contain an index");

    unsigned Calls = 0, Refs = 0, Functions = 0, Alias = 0, Globals = 0;
    for (auto &Summaries : *Index) {
      for (auto &Summary : Summaries.second.SummaryList) {
        Refs += Summary->refs().size();
        if (auto *FuncSummary = dyn_cast<FunctionSummary>(Summary.get())) {
          Functions++;
          Calls += FuncSummary->calls().size();
        } else if (isa<AliasSummary>(Summary.get()))
          Alias++;
        else
          Globals++;
      }
    }
    outs() << "Index " << Filename << " contains "
           << (Alias + Globals + Functions) << " nodes (" << Functions
           << " functions, " << Alias << " alias, " << Globals
           << " globals) and " << (Calls + Refs) << " edges (" << Refs
           << " refs and " << Calls << " calls)\n";
  }
}

/// Print the lto symbol attributes.
static void printLTOSymbolAttributes(lto_symbol_attributes Attrs) {
  outs() << "{ ";
  unsigned Permission = Attrs & LTO_SYMBOL_PERMISSIONS_MASK;
  switch (Permission) {
  case LTO_SYMBOL_PERMISSIONS_CODE:
    outs() << "function ";
    break;
  case LTO_SYMBOL_PERMISSIONS_DATA:
    outs() << "data ";
    break;
  case LTO_SYMBOL_PERMISSIONS_RODATA:
    outs() << "constant ";
    break;
  }
  unsigned Definition = Attrs & LTO_SYMBOL_DEFINITION_MASK;
  switch (Definition) {
  case LTO_SYMBOL_DEFINITION_REGULAR:
    outs() << "defined ";
    break;
  case LTO_SYMBOL_DEFINITION_TENTATIVE:
    outs() << "common ";
    break;
  case LTO_SYMBOL_DEFINITION_WEAK:
    outs() << "weak ";
    break;
  case LTO_SYMBOL_DEFINITION_UNDEFINED:
    outs() << "extern ";
    break;
  case LTO_SYMBOL_DEFINITION_WEAKUNDEF:
    outs() << "extern-weak ";
    break;
  }
  unsigned Scope = Attrs & LTO_SYMBOL_SCOPE_MASK;
  switch (Scope) {
  case LTO_SYMBOL_SCOPE_INTERNAL:
    outs() << "internal ";
    break;
  case LTO_SYMBOL_SCOPE_HIDDEN:
    outs() << "hidden ";
    break;
  case LTO_SYMBOL_SCOPE_PROTECTED:
    outs() << "protected ";
    break;
  case LTO_SYMBOL_SCOPE_DEFAULT:
    outs() << "default ";
    break;
  case LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN:
    outs() << "omitted ";
    break;
  }
  if (Attrs & LTO_SYMBOL_COMDAT)
    outs() << "comdat ";
  if (Attrs & LTO_SYMBOL_ALIAS)
    outs() << "alias ";
  outs() << "}";
}

/// Load each IR file and dump certain information based on active flags.
///
/// The main point here is to provide lit-testable coverage for the LTOModule
/// functionality that's exposed by the C API. Moreover, this provides testing
/// coverage for modules that have been created in their own contexts.
static void testLTOModule(const TargetOptions &Options) {
  for (auto &Filename : InputFilenames) {
    std::unique_ptr<MemoryBuffer> Buffer;
    std::unique_ptr<LTOModule> Module =
        getLocalLTOModule(Filename, Buffer, Options);

    if (ListSymbolsOnly) {
      // List the symbols.
      outs() << Filename << ":\n";
      for (int I = 0, E = Module->getSymbolCount(); I != E; ++I) {
        outs() << Module->getSymbolName(I) << "    ";
        printLTOSymbolAttributes(Module->getSymbolAttributes(I));
        outs() << "\n";
      }
      for (int I = 0, E = Module->getAsmUndefSymbolCount(); I != E; ++I)
        outs() << Module->getAsmUndefSymbolName(I) << "    { asm extern }\n";
    }
    if (QueryHasCtorDtor)
      outs() << Filename
             << ": hasCtorDtor = " << (Module->hasCtorDtor() ? "true" : "false")
             << "\n";
  }
}

static std::unique_ptr<MemoryBuffer> loadFile(StringRef Filename) {
    ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename.str() +
        "': ");
    return ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Filename)));
}

static void listDependentLibraries() {
  for (auto &Filename : InputFilenames) {
    auto Buffer = loadFile(Filename);
    std::string E;
    std::unique_ptr<lto::InputFile> Input(LTOModule::createInputFile(
        Buffer->getBufferStart(), Buffer->getBufferSize(), Filename.c_str(),
        E));
    if (!Input)
      error(E);

    // List the dependent libraries.
    outs() << Filename << ":\n";
    for (size_t I = 0, C = LTOModule::getDependentLibraryCount(Input.get());
         I != C; ++I) {
      size_t L = 0;
      const char *S = LTOModule::getDependentLibrary(Input.get(), I, &L);
      assert(S);
      outs() << StringRef(S, L) << "\n";
    }
  }
}

static void printMachOCPUOnly() {
  LLVMContext Context;
  Context.setDiagnosticHandler(std::make_unique<LLVMLTODiagnosticHandler>(),
                               true);
  TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple());
  for (auto &Filename : InputFilenames) {
    ErrorOr<std::unique_ptr<LTOModule>> ModuleOrErr =
        LTOModule::createFromFile(Context, Filename, Options);
    if (!ModuleOrErr)
      error(ModuleOrErr, "llvm-lto: ");

    Expected<uint32_t> CPUType = (*ModuleOrErr)->getMachOCPUType();
    Expected<uint32_t> CPUSubType = (*ModuleOrErr)->getMachOCPUSubType();
    if (!CPUType)
      error("Error while printing mach-o cputype: " +
            toString(CPUType.takeError()));
    if (!CPUSubType)
      error("Error while printing mach-o cpusubtype: " +
            toString(CPUSubType.takeError()));
    outs() << llvm::format("%s:\ncputype: %u\ncpusubtype: %u\n",
                           Filename.c_str(), *CPUType, *CPUSubType);
  }
}

/// Create a combined index file from the input IR files and write it.
///
/// This is meant to enable testing of ThinLTO combined index generation,
/// currently available via the gold plugin via -thinlto.
static void createCombinedModuleSummaryIndex() {
  ModuleSummaryIndex CombinedIndex(/*HaveGVs=*/false);
  for (auto &Filename : InputFilenames) {
    ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename + "': ");
    std::unique_ptr<MemoryBuffer> MB =
        ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Filename)));
    ExitOnErr(readModuleSummaryIndex(*MB, CombinedIndex));
  }
  // In order to use this index for testing, specifically import testing, we
  // need to update any indirect call edges created from SamplePGO, so that they
  // point to the correct GUIDs.
  updateIndirectCalls(CombinedIndex);
  std::error_code EC;
  assert(!OutputFilename.empty());
  raw_fd_ostream OS(OutputFilename + ".thinlto.bc", EC,
                    sys::fs::OpenFlags::OF_None);
  error(EC, "error opening the file '" + OutputFilename + ".thinlto.bc'");
  writeIndexToFile(CombinedIndex, OS);
  OS.close();
}

/// Parse the thinlto_prefix_replace option into the \p OldPrefix and
/// \p NewPrefix strings, if it was specified.
static void getThinLTOOldAndNewPrefix(std::string &OldPrefix,
                                      std::string &NewPrefix) {
  assert(ThinLTOPrefixReplace.empty() ||
         ThinLTOPrefixReplace.find(';') != StringRef::npos);
  StringRef PrefixReplace = ThinLTOPrefixReplace;
  std::pair<StringRef, StringRef> Split = PrefixReplace.split(";");
  OldPrefix = Split.first.str();
  NewPrefix = Split.second.str();
}

/// Given the original \p Path to an output file, replace any path
/// prefix matching \p OldPrefix with \p NewPrefix. Also, create the
/// resulting directory if it does not yet exist.
static std::string getThinLTOOutputFile(StringRef Path, StringRef OldPrefix,
                                        StringRef NewPrefix) {
  if (OldPrefix.empty() && NewPrefix.empty())
    return std::string(Path);
  SmallString<128> NewPath(Path);
  llvm::sys::path::replace_path_prefix(NewPath, OldPrefix, NewPrefix);
  StringRef ParentPath = llvm::sys::path::parent_path(NewPath.str());
  if (!ParentPath.empty()) {
    // Make sure the new directory exists, creating it if necessary.
    if (std::error_code EC = llvm::sys::fs::create_directories(ParentPath))
      error(EC, "error creating the directory '" + ParentPath + "'");
  }
  return std::string(NewPath);
}

namespace thinlto {

std::vector<std::unique_ptr<MemoryBuffer>>
loadAllFilesForIndex(const ModuleSummaryIndex &Index) {
  std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;

  for (auto &ModPath : Index.modulePaths()) {
    const auto &Filename = ModPath.first();
    std::string CurrentActivity = ("loading file '" + Filename + "'").str();
    auto InputOrErr = MemoryBuffer::getFile(Filename);
    error(InputOrErr, "error " + CurrentActivity);
    InputBuffers.push_back(std::move(*InputOrErr));
  }
  return InputBuffers;
}

std::unique_ptr<ModuleSummaryIndex> loadCombinedIndex() {
  if (ThinLTOIndex.empty())
    report_fatal_error("Missing -thinlto-index for ThinLTO promotion stage");
  ExitOnError ExitOnErr("llvm-lto: error loading file '" + ThinLTOIndex +
                        "': ");
  return ExitOnErr(getModuleSummaryIndexForFile(ThinLTOIndex));
}

static std::unique_ptr<lto::InputFile> loadInputFile(MemoryBufferRef Buffer) {
  ExitOnError ExitOnErr("llvm-lto: error loading input '" +
                        Buffer.getBufferIdentifier().str() + "': ");
  return ExitOnErr(lto::InputFile::create(Buffer));
}

static std::unique_ptr<Module> loadModuleFromInput(lto::InputFile &File,
                                                   LLVMContext &CTX) {
  auto &Mod = File.getSingleBitcodeModule();
  auto ModuleOrErr = Mod.parseModule(CTX);
  if (!ModuleOrErr) {
    handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
      SMDiagnostic Err = SMDiagnostic(Mod.getModuleIdentifier(),
                                      SourceMgr::DK_Error, EIB.message());
      Err.print("llvm-lto", errs());
    });
    report_fatal_error("Can't load module, abort.");
  }
  maybeVerifyModule(**ModuleOrErr);
  if (ThinLTOModuleId.getNumOccurrences()) {
    if (InputFilenames.size() != 1)
      report_fatal_error("Can't override the module id for multiple files");
    (*ModuleOrErr)->setModuleIdentifier(ThinLTOModuleId);
  }
  return std::move(*ModuleOrErr);
}

static void writeModuleToFile(Module &TheModule, StringRef Filename) {
  std::error_code EC;
  raw_fd_ostream OS(Filename, EC, sys::fs::OpenFlags::OF_None);
  error(EC, "error opening the file '" + Filename + "'");
  maybeVerifyModule(TheModule);
  WriteBitcodeToFile(TheModule, OS, /* ShouldPreserveUseListOrder */ true);
}

class ThinLTOProcessing {
public:
  ThinLTOCodeGenerator ThinGenerator;

  ThinLTOProcessing(const TargetOptions &Options) {
    ThinGenerator.setCodePICModel(codegen::getExplicitRelocModel());
    ThinGenerator.setTargetOptions(Options);
    ThinGenerator.setCacheDir(ThinLTOCacheDir);
    ThinGenerator.setCachePruningInterval(ThinLTOCachePruningInterval);
    ThinGenerator.setCacheEntryExpiration(ThinLTOCacheEntryExpiration);
    ThinGenerator.setCacheMaxSizeFiles(ThinLTOCacheMaxSizeFiles);
    ThinGenerator.setCacheMaxSizeBytes(ThinLTOCacheMaxSizeBytes);
    ThinGenerator.setFreestanding(EnableFreestanding);
    ThinGenerator.setDebugPassManager(DebugPassManager);

    // Add all the exported symbols to the table of symbols to preserve.
    for (unsigned i = 0; i < ExportedSymbols.size(); ++i)
      ThinGenerator.preserveSymbol(ExportedSymbols[i]);
  }

  void run() {
    switch (ThinLTOMode) {
    case THINLINK:
      return thinLink();
    case THINDISTRIBUTE:
      return distributedIndexes();
    case THINEMITIMPORTS:
      return emitImports();
    case THINPROMOTE:
      return promote();
    case THINIMPORT:
      return import();
    case THININTERNALIZE:
      return internalize();
    case THINOPT:
      return optimize();
    case THINCODEGEN:
      return codegen();
    case THINALL:
      return runAll();
    }
  }

private:
  /// Load the input files, create the combined index, and write it out.
  void thinLink() {
    // Perform "ThinLink": just produce the index
    if (OutputFilename.empty())
      report_fatal_error(
          "OutputFilename is necessary to store the combined index.\n");

    LLVMContext Ctx;
    std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
    for (unsigned i = 0; i < InputFilenames.size(); ++i) {
      auto &Filename = InputFilenames[i];
      std::string CurrentActivity = "loading file '" + Filename + "'";
      auto InputOrErr = MemoryBuffer::getFile(Filename);
      error(InputOrErr, "error " + CurrentActivity);
      InputBuffers.push_back(std::move(*InputOrErr));
      ThinGenerator.addModule(Filename, InputBuffers.back()->getBuffer());
    }

    auto CombinedIndex = ThinGenerator.linkCombinedIndex();
    if (!CombinedIndex)
      report_fatal_error("ThinLink didn't create an index");
    std::error_code EC;
    raw_fd_ostream OS(OutputFilename, EC, sys::fs::OpenFlags::OF_None);
    error(EC, "error opening the file '" + OutputFilename + "'");
    writeIndexToFile(*CombinedIndex, OS);
  }

  /// Load the combined index from disk, then compute and generate
  /// individual index files suitable for ThinLTO distributed backend builds
  /// on the files mentioned on the command line (these must match the index
  /// content).
  void distributedIndexes() {
    if (InputFilenames.size() != 1 && !OutputFilename.empty())
      report_fatal_error("Can't handle a single output filename and multiple "
                         "input files, do not provide an output filename and "
                         "the output files will be suffixed from the input "
                         "ones.");

    std::string OldPrefix, NewPrefix;
    getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix);

    auto Index = loadCombinedIndex();
    for (auto &Filename : InputFilenames) {
      LLVMContext Ctx;
      auto Buffer = loadFile(Filename);
      auto Input = loadInputFile(Buffer->getMemBufferRef());
      auto TheModule = loadModuleFromInput(*Input, Ctx);

      // Build a map of module to the GUIDs and summary objects that should
      // be written to its index.
      ModuleToSummariesForIndexTy ModuleToSummariesForIndex;
      GVSummaryPtrSet DecSummaries;
      ThinGenerator.gatherImportedSummariesForModule(
          *TheModule, *Index, ModuleToSummariesForIndex, DecSummaries, *Input);

      std::string OutputName = OutputFilename;
      if (OutputName.empty()) {
        OutputName = Filename + ".thinlto.bc";
      }
      OutputName = getThinLTOOutputFile(OutputName, OldPrefix, NewPrefix);
      std::error_code EC;
      raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::OF_None);
      error(EC, "error opening the file '" + OutputName + "'");
      writeIndexToFile(*Index, OS, &ModuleToSummariesForIndex, &DecSummaries);
    }
  }

  /// Load the combined index from disk, compute the imports, and emit
  /// the import file lists for each module to disk.
  void emitImports() {
    if (InputFilenames.size() != 1 && !OutputFilename.empty())
      report_fatal_error("Can't handle a single output filename and multiple "
                         "input files, do not provide an output filename and "
                         "the output files will be suffixed from the input "
                         "ones.");

    std::string OldPrefix, NewPrefix;
    getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix);

    auto Index = loadCombinedIndex();
    for (auto &Filename : InputFilenames) {
      LLVMContext Ctx;
      auto Buffer = loadFile(Filename);
      auto Input = loadInputFile(Buffer->getMemBufferRef());
      auto TheModule = loadModuleFromInput(*Input, Ctx);
      std::string OutputName = OutputFilename;
      if (OutputName.empty()) {
        OutputName = Filename + ".imports";
      }
      OutputName =
          getThinLTOOutputFile(OutputName, OldPrefix, NewPrefix);
      ThinGenerator.emitImports(*TheModule, OutputName, *Index, *Input);
    }
  }

  /// Load the combined index from disk, then load every file referenced by
  /// the index and add them to the generator, finally perform the promotion
  /// on the files mentioned on the command line (these must match the index
  /// content).
  void promote() {
    if (InputFilenames.size() != 1 && !OutputFilename.empty())
      report_fatal_error("Can't handle a single output filename and multiple "
                         "input files, do not provide an output filename and "
                         "the output files will be suffixed from the input "
                         "ones.");

    auto Index = loadCombinedIndex();
    for (auto &Filename : InputFilenames) {
      LLVMContext Ctx;
      auto Buffer = loadFile(Filename);
      auto Input = loadInputFile(Buffer->getMemBufferRef());
      auto TheModule = loadModuleFromInput(*Input, Ctx);

      ThinGenerator.promote(*TheModule, *Index, *Input);

      std::string OutputName = OutputFilename;
      if (OutputName.empty()) {
        OutputName = Filename + ".thinlto.promoted.bc";
      }
      writeModuleToFile(*TheModule, OutputName);
    }
  }

  /// Load the combined index from disk, then load every file referenced by
  /// the index and add them to the generator, then performs the promotion and
  /// cross module importing on the files mentioned on the command line
  /// (these must match the index content).
  void import() {
    if (InputFilenames.size() != 1 && !OutputFilename.empty())
      report_fatal_error("Can't handle a single output filename and multiple "
                         "input files, do not provide an output filename and "
                         "the output files will be suffixed from the input "
                         "ones.");

    auto Index = loadCombinedIndex();
    auto InputBuffers = loadAllFilesForIndex(*Index);
    for (auto &MemBuffer : InputBuffers)
      ThinGenerator.addModule(MemBuffer->getBufferIdentifier(),
                              MemBuffer->getBuffer());

    for (auto &Filename : InputFilenames) {
      LLVMContext Ctx;
      auto Buffer = loadFile(Filename);
      auto Input = loadInputFile(Buffer->getMemBufferRef());
      auto TheModule = loadModuleFromInput(*Input, Ctx);

      ThinGenerator.crossModuleImport(*TheModule, *Index, *Input);

      std::string OutputName = OutputFilename;
      if (OutputName.empty()) {
        OutputName = Filename + ".thinlto.imported.bc";
      }
      writeModuleToFile(*TheModule, OutputName);
    }
  }

  void internalize() {
    if (InputFilenames.size() != 1 && !OutputFilename.empty())
      report_fatal_error("Can't handle a single output filename and multiple "
                         "input files, do not provide an output filename and "
                         "the output files will be suffixed from the input "
                         "ones.");

    if (ExportedSymbols.empty())
      errs() << "Warning: -internalize will not perform without "
                "-exported-symbol\n";

    auto Index = loadCombinedIndex();
    auto InputBuffers = loadAllFilesForIndex(*Index);
    for (auto &MemBuffer : InputBuffers)
      ThinGenerator.addModule(MemBuffer->getBufferIdentifier(),
                              MemBuffer->getBuffer());

    for (auto &Filename : InputFilenames) {
      LLVMContext Ctx;
      auto Buffer = loadFile(Filename);
      auto Input = loadInputFile(Buffer->getMemBufferRef());
      auto TheModule = loadModuleFromInput(*Input, Ctx);

      ThinGenerator.internalize(*TheModule, *Index, *Input);

      std::string OutputName = OutputFilename;
      if (OutputName.empty()) {
        OutputName = Filename + ".thinlto.internalized.bc";
      }
      writeModuleToFile(*TheModule, OutputName);
    }
  }

  void optimize() {
    if (InputFilenames.size() != 1 && !OutputFilename.empty())
      report_fatal_error("Can't handle a single output filename and multiple "
                         "input files, do not provide an output filename and "
                         "the output files will be suffixed from the input "
                         "ones.");
    if (!ThinLTOIndex.empty())
      errs() << "Warning: -thinlto-index ignored for optimize stage";

    for (auto &Filename : InputFilenames) {
      LLVMContext Ctx;
      auto Buffer = loadFile(Filename);
      auto Input = loadInputFile(Buffer->getMemBufferRef());
      auto TheModule = loadModuleFromInput(*Input, Ctx);

      ThinGenerator.optimize(*TheModule);

      std::string OutputName = OutputFilename;
      if (OutputName.empty()) {
        OutputName = Filename + ".thinlto.imported.bc";
      }
      writeModuleToFile(*TheModule, OutputName);
    }
  }

  void codegen() {
    if (InputFilenames.size() != 1 && !OutputFilename.empty())
      report_fatal_error("Can't handle a single output filename and multiple "
                         "input files, do not provide an output filename and "
                         "the output files will be suffixed from the input "
                         "ones.");
    if (!ThinLTOIndex.empty())
      errs() << "Warning: -thinlto-index ignored for codegen stage";

    std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
    for (auto &Filename : InputFilenames) {
      LLVMContext Ctx;
      auto InputOrErr = MemoryBuffer::getFile(Filename);
      error(InputOrErr, "error " + CurrentActivity);
      InputBuffers.push_back(std::move(*InputOrErr));
      ThinGenerator.addModule(Filename, InputBuffers.back()->getBuffer());
    }
    ThinGenerator.setCodeGenOnly(true);
    ThinGenerator.run();
    for (auto BinName :
         zip(ThinGenerator.getProducedBinaries(), InputFilenames)) {
      std::string OutputName = OutputFilename;
      if (OutputName.empty())
        OutputName = std::get<1>(BinName) + ".thinlto.o";
      else if (OutputName == "-") {
        outs() << std::get<0>(BinName)->getBuffer();
        return;
      }

      std::error_code EC;
      raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::OF_None);
      error(EC, "error opening the file '" + OutputName + "'");
      OS << std::get<0>(BinName)->getBuffer();
    }
  }

  /// Full ThinLTO process
  void runAll() {
    if (!OutputFilename.empty())
      report_fatal_error("Do not provide an output filename for ThinLTO "
                         " processing, the output files will be suffixed from "
                         "the input ones.");

    if (!ThinLTOIndex.empty())
      errs() << "Warning: -thinlto-index ignored for full ThinLTO process";

    LLVMContext Ctx;
    std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
    for (unsigned i = 0; i < InputFilenames.size(); ++i) {
      auto &Filename = InputFilenames[i];
      std::string CurrentActivity = "loading file '" + Filename + "'";
      auto InputOrErr = MemoryBuffer::getFile(Filename);
      error(InputOrErr, "error " + CurrentActivity);
      InputBuffers.push_back(std::move(*InputOrErr));
      ThinGenerator.addModule(Filename, InputBuffers.back()->getBuffer());
    }

    if (!ThinLTOSaveTempsPrefix.empty())
      ThinGenerator.setSaveTempsDir(ThinLTOSaveTempsPrefix);

    if (!ThinLTOGeneratedObjectsDir.empty()) {
      ThinGenerator.setGeneratedObjectsDirectory(ThinLTOGeneratedObjectsDir);
      ThinGenerator.run();
      return;
    }

    ThinGenerator.run();

    auto &Binaries = ThinGenerator.getProducedBinaries();
    if (Binaries.size() != InputFilenames.size())
      report_fatal_error("Number of output objects does not match the number "
                         "of inputs");

    for (unsigned BufID = 0; BufID < Binaries.size(); ++BufID) {
      auto OutputName = InputFilenames[BufID] + ".thinlto.o";
      std::error_code EC;
      raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::OF_None);
      error(EC, "error opening the file '" + OutputName + "'");
      OS << Binaries[BufID]->getBuffer();
    }
  }

  /// Load the combined index from disk, then load every file referenced by
};

} // end namespace thinlto

int main(int argc, char **argv) {
  InitLLVM X(argc, argv);
  cl::HideUnrelatedOptions({&LTOCategory, &getColorCategory()});
  cl::ParseCommandLineOptions(argc, argv, "llvm LTO linker\n");

  if (OptLevel < '0' || OptLevel > '3')
    error("optimization level must be between 0 and 3");

  // Initialize the configured targets.
  InitializeAllTargets();
  InitializeAllTargetMCs();
  InitializeAllAsmPrinters();
  InitializeAllAsmParsers();

  // set up the TargetOptions for the machine
  TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple());

  if (ListSymbolsOnly || QueryHasCtorDtor) {
    testLTOModule(Options);
    return 0;
  }

  if (ListDependentLibrariesOnly) {
    listDependentLibraries();
    return 0;
  }

  if (IndexStats) {
    printIndexStats();
    return 0;
  }

  if (CheckHasObjC) {
    for (auto &Filename : InputFilenames) {
      ExitOnError ExitOnErr(std::string(*argv) + ": error loading file '" +
                            Filename + "': ");
      std::unique_ptr<MemoryBuffer> BufferOrErr =
          ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(Filename)));
      auto Buffer = std::move(BufferOrErr.get());
      if (ExitOnErr(isBitcodeContainingObjCCategory(*Buffer)))
        outs() << "Bitcode " << Filename << " contains ObjC\n";
      else
        outs() << "Bitcode " << Filename << " does not contain ObjC\n";
    }
    return 0;
  }

  if (PrintMachOCPUOnly) {
    printMachOCPUOnly();
    return 0;
  }

  if (ThinLTOMode.getNumOccurrences()) {
    if (ThinLTOMode.getNumOccurrences() > 1)
      report_fatal_error("You can't specify more than one -thinlto-action");
    thinlto::ThinLTOProcessing ThinLTOProcessor(Options);
    ThinLTOProcessor.run();
    return 0;
  }

  if (ThinLTO) {
    createCombinedModuleSummaryIndex();
    return 0;
  }

  unsigned BaseArg = 0;

  LLVMContext Context;
  Context.setDiagnosticHandler(std::make_unique<LLVMLTODiagnosticHandler>(),
                               true);

  LTOCodeGenerator CodeGen(Context);
  CodeGen.setDisableVerify(DisableVerify);

  if (UseDiagnosticHandler)
    CodeGen.setDiagnosticHandler(handleDiagnostics, nullptr);

  CodeGen.setCodePICModel(codegen::getExplicitRelocModel());
  CodeGen.setFreestanding(EnableFreestanding);
  CodeGen.setDebugPassManager(DebugPassManager);

  CodeGen.setDebugInfo(LTO_DEBUG_MODEL_DWARF);
  CodeGen.setTargetOptions(Options);
  CodeGen.setShouldRestoreGlobalsLinkage(RestoreGlobalsLinkage);

  StringSet<MallocAllocator> DSOSymbolsSet(llvm::from_range, DSOSymbols);

  std::vector<std::string> KeptDSOSyms;

  for (unsigned i = BaseArg; i < InputFilenames.size(); ++i) {
    CurrentActivity = "loading file '" + InputFilenames[i] + "'";
    ErrorOr<std::unique_ptr<LTOModule>> ModuleOrErr =
        LTOModule::createFromFile(Context, InputFilenames[i], Options);
    std::unique_ptr<LTOModule> &Module = *ModuleOrErr;
    CurrentActivity = "";

    unsigned NumSyms = Module->getSymbolCount();
    for (unsigned I = 0; I < NumSyms; ++I) {
      StringRef Name = Module->getSymbolName(I);
      if (!DSOSymbolsSet.count(Name))
        continue;
      lto_symbol_attributes Attrs = Module->getSymbolAttributes(I);
      unsigned Scope = Attrs & LTO_SYMBOL_SCOPE_MASK;
      if (Scope != LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN)
        KeptDSOSyms.push_back(std::string(Name));
    }

    // We use the first input module as the destination module when
    // SetMergedModule is true.
    if (SetMergedModule && i == BaseArg) {
      // Transfer ownership to the code generator.
      CodeGen.setModule(std::move(Module));
    } else if (!CodeGen.addModule(Module.get())) {
      // Print a message here so that we know addModule() did not abort.
      error("error adding file '" + InputFilenames[i] + "'");
    }
  }

  // Add all the exported symbols to the table of symbols to preserve.
  for (unsigned i = 0; i < ExportedSymbols.size(); ++i)
    CodeGen.addMustPreserveSymbol(ExportedSymbols[i]);

  // Add all the dso symbols to the table of symbols to expose.
  for (unsigned i = 0; i < KeptDSOSyms.size(); ++i)
    CodeGen.addMustPreserveSymbol(KeptDSOSyms[i]);

  // Set cpu and attrs strings for the default target/subtarget.
  CodeGen.setCpu(codegen::getMCPU());

  CodeGen.setOptLevel(OptLevel - '0');
  CodeGen.setAttrs(codegen::getMAttrs());

  if (auto FT = codegen::getExplicitFileType())
    CodeGen.setFileType(*FT);

  if (!OutputFilename.empty()) {
    if (LTOSaveBeforeOpt)
      CodeGen.setSaveIRBeforeOptPath(OutputFilename + ".0.preopt.bc");

    if (SaveLinkedModuleFile) {
      std::string ModuleFilename = OutputFilename;
      ModuleFilename += ".linked.bc";

      if (!CodeGen.writeMergedModules(ModuleFilename))
        error("writing linked module failed.");
    }

    if (!CodeGen.optimize()) {
      // Diagnostic messages should have been printed by the handler.
      error("error optimizing the code");
    }

    if (SaveModuleFile) {
      std::string ModuleFilename = OutputFilename;
      ModuleFilename += ".merged.bc";

      if (!CodeGen.writeMergedModules(ModuleFilename))
        error("writing merged module failed.");
    }

    auto AddStream =
        [&](size_t Task,
            const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> {
      std::string PartFilename = OutputFilename;
      if (Parallelism != 1)
        PartFilename += "." + utostr(Task);

      std::error_code EC;
      auto S =
          std::make_unique<raw_fd_ostream>(PartFilename, EC, sys::fs::OF_None);
      if (EC)
        error("error opening the file '" + PartFilename + "': " + EC.message());
      return std::make_unique<CachedFileStream>(std::move(S));
    };

    if (!CodeGen.compileOptimized(AddStream, Parallelism))
      // Diagnostic messages should have been printed by the handler.
      error("error compiling the code");

  } else {
    if (Parallelism != 1)
      error("-j must be specified together with -o");

    if (SaveModuleFile)
      error(": -save-merged-module must be specified with -o");

    const char *OutputName = nullptr;
    if (!CodeGen.compile_to_file(&OutputName))
      error("error compiling the code");
      // Diagnostic messages should have been printed by the handler.

    outs() << "Wrote native object file '" << OutputName << "'\n";
  }

  return 0;
}
