// Copyright 2020 The IREE Authors
//
// Licensed 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

#include "compiler/plugins/target/LLVMCPU/LinkerTool.h"
#include "iree/compiler/Utils/ToolUtils.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/FormatVariadic.h"

#define DEBUG_TYPE "llvm-linker"

namespace mlir::iree_compiler::IREE::HAL {

// Windows linker (MSVC link.exe-like); for DLL files.
class WindowsLinkerTool : public LinkerTool {
public:
  using LinkerTool::LinkerTool;

  std::string getSystemToolPath() const override {
    // First check for setting the linker explicitly.
    auto toolPath = LinkerTool::getSystemToolPath();
    if (!toolPath.empty())
      return toolPath;

    // No explicit linker specified, search the executable directory (i.e. our
    // own build or install directories) for common tools.
    toolPath = findToolFromExecutableDir({"lld-link"});
    if (!toolPath.empty())
      return toolPath;

    llvm::errs() << "No Windows linker tool specified or discovered\n";
    return "";
  }

  LogicalResult
  configureModule(llvm::Module *llvmModule,
                  ArrayRef<llvm::Function *> exportedFuncs) override {
    auto &ctx = llvmModule->getContext();

    // Create a _DllMainCRTStartup replacement that does not initialize the CRT.
    // This is required to prevent a bunch of CRT junk (locale, errno, TLS, etc)
    // from getting emitted in such a way that it cannot be stripped by LTCG.
    // Since we don't emit code using the CRT (beyond memset/memcpy) this is
    // fine and can reduce binary sizes by 50-100KB.
    //
    // More info:
    // https://docs.microsoft.com/en-us/cpp/build/run-time-library-behavior?view=vs-2019
    {
      auto dwordType = llvm::IntegerType::get(ctx, 32);
      auto ptrType = llvm::PointerType::getUnqual(dwordType);
      auto entry = cast<llvm::Function>(
          llvmModule
              ->getOrInsertFunction("iree_dll_main", dwordType, ptrType,
                                    dwordType, ptrType)
              .getCallee());
      entry->setCallingConv(llvm::CallingConv::X86_StdCall);
      entry->setDLLStorageClass(
          llvm::GlobalValue::DLLStorageClassTypes::DLLExportStorageClass);
      entry->setLinkage(llvm::GlobalValue::LinkageTypes::ExternalLinkage);
      auto *block = llvm::BasicBlock::Create(ctx, "entry", entry);
      llvm::IRBuilder<> builder(block);
      auto one = llvm::ConstantInt::get(dwordType, 1, false);
      builder.CreateRet(one);
    }

    // Since all exports are fetched via the executable library query function
    // we don't need to make them publicly exported on the module. This has
    // the downside of making some tooling (disassemblers/decompilers/binary
    // size analysis tools/etc) a bit harder to work with, though, so when
    // compiling in debug mode we export all the functions.
    if (targetOptions.target.debugSymbols) {
      for (auto *llvmFunc : exportedFuncs) {
        llvmFunc->setVisibility(
            llvm::GlobalValue::VisibilityTypes::DefaultVisibility);
        llvmFunc->setLinkage(llvm::GlobalValue::LinkageTypes::ExternalLinkage);
        llvmFunc->setDLLStorageClass(
            llvm::GlobalValue::DLLStorageClassTypes::DLLExportStorageClass);

        // In debug modes we need unwind tables in order to get proper stacks on
        // all platforms. We don't support exceptions so unless debugging is
        // requested we omit them to reduce code size.
        llvmFunc->setUWTableKind(llvm::UWTableKind::Async);
      }
    }

    return success();
  }

  std::optional<Artifacts>
  linkDynamicLibrary(StringRef libraryName,
                     ArrayRef<Artifact> objectFiles) override {
    Artifacts artifacts;

    // Create the shared object name; if we only have a single input object we
    // can just reuse that.
    if (objectFiles.size() == 1) {
      artifacts.libraryFile =
          Artifact::createVariant(objectFiles.front().path, "dll");
    } else {
      artifacts.libraryFile = Artifact::createTemporary(libraryName, "dll");
    }

    // link.exe doesn't like the files being opened. We don't use them as
    // streams so close them all now before running the linker.
    artifacts.libraryFile.close();

    // We need a full path for the PDB and I hate strings in LLVM grumble.
    SmallString<32> pdbPath(artifacts.libraryFile.path);
    llvm::sys::path::replace_extension(pdbPath, "pdb");

    SmallVector<std::string, 8> flags = {
        getSystemToolPath(),

        // Hide the linker banner message printed each time.
        "/nologo",

        // Useful when debugging linking/loading issues:
        // "/verbose",

        // https://docs.microsoft.com/en-us/cpp/build/reference/dll-build-a-dll?view=vs-2019
        // Builds a DLL and exports functions with the dllexport storage class.
        "/dll",

        // Forces a fixed timestamp to ensure files are reproducible across
        // builds. Undocumented but accepted by both link and lld-link.
        // https://blog.conan.io/2019/09/02/Deterministic-builds-with-C-C++.html
        "/Brepro",

        // https://docs.microsoft.com/en-us/cpp/build/reference/nodefaultlib-ignore-libraries?view=vs-2019
        // Ignore any libraries that are specified by the platform as we
        // directly provide the ones we want.
        "/nodefaultlib",

        // https://docs.microsoft.com/en-us/cpp/build/reference/incremental-link-incrementally?view=vs-2019
        // Disable incremental linking as we are only ever linking in one-shot
        // mode to temp files. This avoids additional file padding and ordering
        // restrictions that enable incremental linking. Our other options will
        // prevent incremental linking in most cases, but it doesn't hurt to be
        // explicit.
        "/incremental:no",

        // https://docs.microsoft.com/en-us/cpp/build/reference/guard-enable-guard-checks?view=vs-2019
        // No control flow guard lookup (indirect branch verification).
        "/guard:no",

        // https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers?view=vs-2019
        // We don't want exception unwind tables in our output.
        "/safeseh:no",

        // https://docs.microsoft.com/en-us/cpp/build/reference/entry-entry-point-symbol?view=vs-2019
        // Use our entry point instead of the standard CRT one; ensures that we
        // pull in no global state from the CRT.
        "/entry:iree_dll_main",

        // https://docs.microsoft.com/en-us/cpp/build/reference/debug-generate-debug-info?view=vs-2019
        // Copies all PDB information into the final PDB so that we can use the
        // same PDB across multiple machines.
        "/debug:full",

        // https://docs.microsoft.com/en-us/cpp/build/reference/pdb-use-program-database
        // Generates the PDB file containing the debug information.
        ("/pdb:" + pdbPath).str(),

        // https://docs.microsoft.com/en-us/cpp/build/reference/pdbaltpath-use-alternate-pdb-path?view=vs-2019
        // Forces the PDB we generate to be referenced in the DLL as just a
        // relative path to the DLL itself. This allows us to move the PDBs
        // along with the build DLLs across machines.
        "/pdbaltpath:%_PDB%",

        // https://docs.microsoft.com/en-us/cpp/build/reference/out-output-file-name?view=vs-2019
        // Target for linker output. The base name of this path will be used for
        // additional output files (like the map and pdb).
        "/out:" + artifacts.libraryFile.path,
    };

    if (targetOptions.target.optimizerOptLevel.getSpeedupLevel() >= 2 ||
        targetOptions.target.optimizerOptLevel.getSizeLevel() >= 2) {
      // https://docs.microsoft.com/en-us/cpp/build/reference/opt-optimizations?view=vs-2019
      // Enable all the fancy optimizations.
      flags.push_back("/opt:ref,icf,lbr");
    }

    // SDK and MSVC paths.
    // These rely on the environment variables provided by the
    // vcvarsall or VsDevCmd ("Developer Command Prompt") scripts. They can also
    // be manually be specified.
    //
    // We could also check to see if vswhere is installed and query that in the
    // event of missing environment variables; that would eliminate the need for
    // specifying things from for example IDEs that may not bring in the vcvars.
    //
    /* Example values:
      UCRTVersion=10.0.18362.0
      UniversalCRTSdkDir=C:\Program Files (x86)\Windows Kits\10\
      VCToolsInstallDir=C:\Program Files (x86)\Microsoft Visual
          Studio\2019\Preview\VC\Tools\MSVC\14.28.29304\
      */
    if (!getenv("VCToolsInstallDir") || !getenv("UniversalCRTSdkDir")) {
      llvm::errs() << "required environment for lld-link/link not specified; "
                      "ensure you are building from a shell where "
                      "vcvarsall/VsDevCmd.bat/etc has been used\n";
      return std::nullopt;
    }
    const char *arch;
    if (targetTriple.isARM() && targetTriple.isArch32Bit()) {
      arch = "arm";
    } else if (targetTriple.isARM()) {
      arch = "arm64";
    } else if (targetTriple.isX86() && targetTriple.isArch32Bit()) {
      arch = "x86";
    } else if (targetTriple.isX86()) {
      arch = "x64";
    } else {
      llvm::errs() << "unsupported Windows target triple (no arch libs): "
                   << targetTriple.str();
      return std::nullopt;
    }
    flags.push_back(
        llvm::formatv("/libpath:\"{0}\\lib\\{1}\"", "%VCToolsInstallDir%", arch)
            .str());
    flags.push_back(llvm::formatv("/libpath:\"{0}\\Lib\\{1}\\ucrt\\{2}\"",
                                  "%UniversalCRTSdkDir%", "%UCRTVersion%", arch)
                        .str());
    flags.push_back(llvm::formatv("/libpath:\"{0}\\Lib\\{1}\\um\\{2}\"",
                                  "%UniversalCRTSdkDir%", "%UCRTVersion%", arch)
                        .str());

    // We need to link against different libraries based on our configuration
    // matrix (dynamic/static and debug/release).
    int libIndex = 0;
    if (targetOptions.target.optimizerOptLevel.getSpeedupLevel() == 0) {
      libIndex += 0; // debug
    } else {
      libIndex += 2; // release
    }
    libIndex += targetOptions.target.linkStatic ? 1 : 0;

    // The required libraries for linking DLLs:
    // https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=msvc-160
    //
    // NOTE: there are only static versions of msvcrt as it's the startup code.
    static const char *kMSVCRTLibs[4] = {
        /*   debug/dynamic */ "msvcrtd.lib",
        /*   debug/static  */ "msvcrtd.lib",
        /* release/dynamic */ "msvcrt.lib",
        /* release/static  */ "msvcrt.lib",
    };
    static const char *kVCRuntimeLibs[4] = {
        /*   debug/dynamic */ "vcruntimed.lib",
        /*   debug/static  */ "libvcruntimed.lib",
        /* release/dynamic */ "vcruntime.lib",
        /* release/static  */ "libvcruntime.lib",
    };
    static const char *kUCRTLibs[4] = {
        /*   debug/dynamic */ "ucrtd.lib",
        /*   debug/static  */ "libucrtd.lib",
        /* release/dynamic */ "ucrt.lib",
        /* release/static  */ "libucrt.lib",
    };
    flags.push_back(kMSVCRTLibs[libIndex]);
    flags.push_back(kVCRuntimeLibs[libIndex]);
    flags.push_back(kUCRTLibs[libIndex]);
    flags.push_back("kernel32.lib");

    // Link all input objects. Note that we are not linking whole-archive as we
    // want to allow dropping of unused codegen outputs.
    for (auto &objectFile : objectFiles) {
      flags.push_back(objectFile.path);
    }

    auto commandLine = llvm::join(flags, " ");
    if (failed(runLinkCommand(commandLine)))
      return std::nullopt;

    // PDB file gets generated wtih the same path + .pdb.
    artifacts.debugFile =
        Artifact::createVariant(artifacts.libraryFile.path, "pdb");

    // We currently discard some of the other file outputs (like the .exp
    // listing the exported symbols) as we don't need them.
    artifacts.otherFiles.push_back(
        Artifact::createVariant(artifacts.libraryFile.path, "exp"));
    artifacts.otherFiles.push_back(
        Artifact::createVariant(artifacts.libraryFile.path, "lib"));

    return artifacts;
  }
};

std::unique_ptr<LinkerTool>
createWindowsLinkerTool(const llvm::Triple &targetTriple,
                        LLVMTargetOptions &targetOptions) {
  return std::make_unique<WindowsLinkerTool>(targetTriple, targetOptions);
}

} // namespace mlir::iree_compiler::IREE::HAL
