#include "clang/Basic/TargetID.h"
#include "clang/Basic/Version.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/Frontend/Offloading/OffloadWrapper.h"
#include "llvm/Frontend/Offloading/Utility.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/Module.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/LTO/LTO.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/ArchiveWriter.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/OffloadBinary.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Remarks/HotnessThresholdParser.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Parallel.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/StringSaver.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/TargetParser/Host.h"
#include <atomic>
#include <optional>
usingnamespacellvm;
usingnamespacellvm::opt;
usingnamespacellvm::object;
static cl::opt<bool> RemarksWithHotness(
"pass-remarks-with-hotness",
cl::desc("With PGO, include profile count in optimization remarks"),
cl::Hidden);
static 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("N 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::list<std::string>
PassPlugins("load-pass-plugin",
cl::desc("Load passes from plugin library"));
static cl::opt<std::string> PassPipeline(
"passes",
cl::desc(
"A textual description of the pass pipeline. To have analysis passes "
"available before a certain pass, add 'require<foo-analysis>'. "
"'-passes' overrides the pass pipeline (but not all effects) from "
"specifying '--opt-level=O?' (O2 is the default) to "
"clang-linker-wrapper. Be sure to include the corresponding "
"'default<O?>' in '-passes'."));
static cl::alias PassPipeline2("p", cl::aliasopt(PassPipeline),
cl::desc("Alias for -passes"));
static const char *LinkerExecutable;
static bool SaveTemps = …;
static bool DryRun = …;
static bool Verbose = …;
static StringRef ExecutableName;
static std::string CudaBinaryPath;
static std::mutex TempFilesMutex;
static std::list<SmallString<128>> TempFiles;
static codegen::RegisterCodeGenFlags CodeGenFlags;
static std::atomic<bool> LTOError;
OffloadingImage;
namespace llvm {
template <> struct DenseMapInfo<OffloadKind> { … };
}
namespace {
error_code;
enum WrapperFlags { … };
enum ID { … };
#define PREFIX …
#include "LinkerWrapperOpts.inc"
#undef PREFIX
static constexpr OptTable::Info InfoTable[] = …;
class WrapperOptTable : public opt::GenericOptTable { … };
const OptTable &getOptTable() { … }
void printCommands(ArrayRef<StringRef> CmdArgs) { … }
[[noreturn]] void reportError(Error E) { … }
Expected<OffloadFile> getInputBitcodeLibrary(StringRef Input) { … }
std::string getMainExecutable(const char *Name) { … }
Expected<StringRef> createOutputFile(const Twine &Prefix, StringRef Extension) { … }
Error executeCommands(StringRef ExecutablePath, ArrayRef<StringRef> Args) { … }
Expected<std::string> findProgram(StringRef Name, ArrayRef<StringRef> Paths) { … }
bool linkerSupportsLTO(const ArgList &Args) { … }
std::string getHash(StringRef Str) { … }
Error relocateOffloadSection(const ArgList &Args, StringRef Output) { … }
Error runLinker(ArrayRef<StringRef> Files, const ArgList &Args) { … }
void printVersion(raw_ostream &OS) { … }
namespace nvptx {
Expected<StringRef>
fatbinary(ArrayRef<std::pair<StringRef, StringRef>> InputFiles,
const ArgList &Args) { … }
}
namespace amdgcn {
Expected<StringRef>
fatbinary(ArrayRef<std::pair<StringRef, StringRef>> InputFiles,
const ArgList &Args) { … }
}
namespace generic {
Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, const ArgList &Args) { … }
}
Expected<StringRef> linkDevice(ArrayRef<StringRef> InputFiles,
const ArgList &Args) { … }
void diagnosticHandler(const DiagnosticInfo &DI) { … }
std::vector<std::string> getTargetFeatures(ArrayRef<OffloadFile> InputFiles) { … }
template <typename ModuleHook = function_ref<bool(size_t, const Module &)>>
std::unique_ptr<lto::LTO> createLTO(
const ArgList &Args, const std::vector<std::string> &Features,
ModuleHook Hook = [](size_t, const Module &) { … }
bool isValidCIdentifier(StringRef S) { … }
Error linkBitcodeFiles(SmallVectorImpl<OffloadFile> &InputFiles,
SmallVectorImpl<StringRef> &OutputFiles,
const ArgList &Args) { … }
Expected<StringRef> writeOffloadFile(const OffloadFile &File) { … }
Expected<StringRef> compileModule(Module &M, OffloadKind Kind) { … }
Expected<StringRef>
wrapDeviceImages(ArrayRef<std::unique_ptr<MemoryBuffer>> Buffers,
const ArgList &Args, OffloadKind Kind) { … }
Expected<SmallVector<std::unique_ptr<MemoryBuffer>>>
bundleOpenMP(ArrayRef<OffloadingImage> Images) { … }
Expected<SmallVector<std::unique_ptr<MemoryBuffer>>>
bundleCuda(ArrayRef<OffloadingImage> Images, const ArgList &Args) { … }
Expected<SmallVector<std::unique_ptr<MemoryBuffer>>>
bundleHIP(ArrayRef<OffloadingImage> Images, const ArgList &Args) { … }
Expected<SmallVector<std::unique_ptr<MemoryBuffer>>>
bundleLinkedOutput(ArrayRef<OffloadingImage> Images, const ArgList &Args,
OffloadKind Kind) { … }
DerivedArgList getLinkerArgs(ArrayRef<OffloadFile> Input,
const InputArgList &Args) { … }
Error handleOverrideImages(
const InputArgList &Args,
MapVector<OffloadKind, SmallVector<OffloadingImage, 0>> &Images) { … }
Expected<SmallVector<StringRef>> linkAndWrapDeviceFiles(
SmallVectorImpl<SmallVector<OffloadFile>> &LinkerInputFiles,
const InputArgList &Args, char **Argv, int Argc) { … }
std::optional<std::string> findFile(StringRef Dir, StringRef Root,
const Twine &Name) { … }
std::optional<std::string>
findFromSearchPaths(StringRef Name, StringRef Root,
ArrayRef<StringRef> SearchPaths) { … }
std::optional<std::string>
searchLibraryBaseName(StringRef Name, StringRef Root,
ArrayRef<StringRef> SearchPaths) { … }
std::optional<std::string> searchLibrary(StringRef Input, StringRef Root,
ArrayRef<StringRef> SearchPaths) { … }
enum Symbol : uint32_t { … };
Expected<bool> getSymbolsFromBitcode(MemoryBufferRef Buffer, OffloadKind Kind,
bool IsArchive, StringSaver &Saver,
DenseMap<StringRef, Symbol> &Syms) { … }
Expected<bool> getSymbolsFromObject(const ObjectFile &Obj, OffloadKind Kind,
bool IsArchive, StringSaver &Saver,
DenseMap<StringRef, Symbol> &Syms) { … }
Expected<bool> getSymbols(StringRef Image, OffloadKind Kind, bool IsArchive,
StringSaver &Saver,
DenseMap<StringRef, Symbol> &Syms) { … }
Expected<SmallVector<SmallVector<OffloadFile>>>
getDeviceInput(const ArgList &Args) { … }
}
int main(int Argc, char **Argv) { … }