// 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(ctx);
      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:\"{}\\lib\\{}\"", "%VCToolsInstallDir%", arch)
            .str());
    flags.push_back(llvm::formatv("/libpath:\"{}\\Lib\\{}\\ucrt\\{}\"",
                                  "%UniversalCRTSdkDir%", "%UCRTVersion%", arch)
                        .str());
    flags.push_back(llvm::formatv("/libpath:\"{}\\Lib\\{}\\um\\{}\"",
                                  "%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
