llvm/llvm/tools/llvm-lto2/llvm-lto2.cpp

//===-- llvm-lto2: test harness for the resolution-based LTO interface ----===//
//
// 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 and performs
// link-time optimization according to the provided symbol resolutions using the
// resolution-based LTO interface, and outputs one or more object files.
//
// This program is intended to eventually replace llvm-lto which uses the legacy
// LTO interface.
//
//===----------------------------------------------------------------------===//

#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/LTO/LTO.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Remarks/HotnessThresholdParser.h"
#include "llvm/Support/Caching.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/Threading.h"
#include <atomic>

usingnamespacellvm;
usingnamespacelto;

static codegen::RegisterCodeGenFlags CGF;

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

static cl::opt<char> CGOptLevel(
    "cg-opt-level",
    cl::desc("Codegen optimization level (0, 1, 2 or 3, default = '2')"),
    cl::init('2'));

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

static cl::opt<std::string> OutputFilename("o", cl::Required,
                                           cl::desc("Output filename"),
                                           cl::value_desc("filename"));

static cl::opt<std::string> CacheDir("cache-dir", cl::desc("Cache Directory"),
                                     cl::value_desc("directory"));

static cl::opt<std::string> OptPipeline("opt-pipeline",
                                        cl::desc("Optimizer Pipeline"),
                                        cl::value_desc("pipeline"));

static cl::opt<std::string> AAPipeline("aa-pipeline",
                                       cl::desc("Alias Analysis Pipeline"),
                                       cl::value_desc("aapipeline"));

static cl::opt<bool> SaveTemps("save-temps", cl::desc("Save temporary files"));

static cl::list<std::string> SelectSaveTemps(
    "select-save-temps",
    cl::value_desc("One, or multiple of: "
                   "resolution,preopt,promote,internalize,import,opt,precodegen"
                   ",combinedindex"),
    cl::desc("Save selected temporary files. Cannot be specified together with "
             "-save-temps"),
    cl::CommaSeparated);

constexpr const char *SaveTempsValues[] =;

static cl::opt<bool>
    ThinLTODistributedIndexes("thinlto-distributed-indexes",
                              cl::desc("Write out individual index and "
                                       "import files for the "
                                       "distributed backend case"));

static cl::opt<bool>
    ThinLTOEmitIndexes("thinlto-emit-indexes",
                       cl::desc("Write out individual index files via "
                                "InProcessThinLTO"));

static cl::opt<bool>
    ThinLTOEmitImports("thinlto-emit-imports",
                       cl::desc("Write out individual imports files via "
                                "InProcessThinLTO. Has no effect unless "
                                "specified with -thinlto-emit-indexes or "
                                "-thinlto-distributed-indexes"));

// Default to using all available threads in the system, but using only one
// thread per core (no SMT).
// Use -thinlto-threads=all to use hardware_concurrency() instead, which means
// to use all hardware threads or cores in the system.
static cl::opt<std::string> Threads("thinlto-threads");

static cl::list<std::string> SymbolResolutions(
    "r",
    cl::desc("Specify a symbol resolution: filename,symbolname,resolution\n"
             "where \"resolution\" is a sequence (which may be empty) of the\n"
             "following characters:\n"
             " p - prevailing: the linker has chosen this definition of the\n"
             "     symbol\n"
             " l - local: the definition of this symbol is unpreemptable at\n"
             "     runtime and is known to be in this linkage unit\n"
             " x - externally visible: the definition of this symbol is\n"
             "     visible outside of the LTO unit\n"
             "A resolution for each symbol must be specified"));

static cl::opt<std::string> OverrideTriple(
    "override-triple",
    cl::desc("Replace target triples in input files with this triple"));

static cl::opt<std::string> DefaultTriple(
    "default-triple",
    cl::desc(
        "Replace unspecified target triples in input files with this triple"));

static cl::opt<bool> RemarksWithHotness(
    "pass-remarks-with-hotness",
    cl::desc("With PGO, include profile count in optimization remarks"),
    cl::Hidden);

cl::opt<std::optional<uint64_t>, false, remarks::HotnessThresholdParser>
    RemarksHotnessThreshold(
        "pass-remarks-hotness-threshold",
        cl::desc("Minimum profile count required for an "
                 "optimization remark to be output."
                 " Use 'auto' to apply the threshold from profile summary."),
        cl::value_desc("uint or 'auto'"), cl::init(0), cl::Hidden);

static cl::opt<std::string>
    RemarksFilename("pass-remarks-output",
                    cl::desc("Output filename for pass remarks"),
                    cl::value_desc("filename"));

static cl::opt<std::string>
    RemarksPasses("pass-remarks-filter",
                  cl::desc("Only record optimization remarks from passes whose "
                           "names match the given regular expression"),
                  cl::value_desc("regex"));

static cl::opt<std::string> RemarksFormat(
    "pass-remarks-format",
    cl::desc("The format used for serializing remarks (default: YAML)"),
    cl::value_desc("format"), cl::init("yaml"));

static cl::opt<std::string>
    SamplePGOFile("lto-sample-profile-file",
                  cl::desc("Specify a SamplePGO profile file"));

static cl::opt<std::string>
    CSPGOFile("lto-cspgo-profile-file",
              cl::desc("Specify a context sensitive PGO profile file"));

static cl::opt<bool>
    RunCSIRInstr("lto-cspgo-gen",
                 cl::desc("Run PGO context sensitive IR instrumentation"),
                 cl::Hidden);

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

static cl::opt<std::string>
    StatsFile("stats-file", cl::desc("Filename to write statistics to"));

static cl::list<std::string>
    PassPlugins("load-pass-plugin",
                cl::desc("Load passes from plugin library"));

static cl::opt<std::string> UnifiedLTOMode("unified-lto", cl::Optional,
                                           cl::desc("Set LTO mode"),
                                           cl::value_desc("mode"));

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

static cl::opt<bool> TryUseNewDbgInfoFormat(
    "try-experimental-debuginfo-iterators",
    cl::desc("Enable debuginfo iterator positions, if they're built in"),
    cl::init(false), cl::Hidden);

extern cl::opt<bool> UseNewDbgInfoFormat;
extern cl::opt<cl::boolOrDefault> LoadBitcodeIntoNewDbgInfoFormat;
extern cl::opt<cl::boolOrDefault> PreserveInputDbgFormat;

static void check(Error E, std::string Msg) {}

template <typename T> static T check(Expected<T> E, std::string Msg) {}

static void check(std::error_code EC, std::string Msg) {}

template <typename T> static T check(ErrorOr<T> E, std::string Msg) {}

static int usage() {}

static int run(int argc, char **argv) {}

static int dumpSymtab(int argc, char **argv) {}

int main(int argc, char **argv) {}