// Copyright 2021 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 {

// Wasm linker using wasm-ld for producing WebAssembly binaries.
// wasm-ld behaves like traditional ELF linkers and uses similar flags.
//
// For details on the linking process and file formats, see:
// * https://lld.llvm.org/WebAssembly.html
// * https://github.com/WebAssembly/tool-conventions/blob/main/Linking.md
//
// For more background on WebAssembly, see:
// * https://webassembly.org/
// * https://developer.mozilla.org/en-US/docs/WebAssembly
//
// When working with WebAssembly files, these projects are useful:
// * https://github.com/WebAssembly/wabt
// * https://github.com/bytecodealliance/wasmtime
//
// Use with `-iree-llvmcpu-target-triple=wasm32-unknown-unknown` (or
// equivalent). For SIMD support, also set
// `-iree-llvmcpu-target-cpu-features=+simd128`.
class WasmLinkerTool : public LinkerTool {
public:
  using LinkerTool::LinkerTool;

  std::string getWasmToolPath() const {
    // Always use the --iree-llvmcpu-wasm-linker-path flag when specified as
    // it's explicitly telling us what to use.
    if (!targetOptions.wasmLinkerPath.empty()) {
      return targetOptions.wasmLinkerPath;
    }

    // Allow overriding the automatic search with an environment variable.
    char *linkerPath = std::getenv("IREE_LLVM_WASM_LINKER_PATH");
    if (linkerPath) {
      return std::string(linkerPath);
    }

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

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

  LogicalResult
  configureModule(llvm::Module *llvmModule,
                  ArrayRef<llvm::Function *> exportedFuncs) override {
    // https://lld.llvm.org/WebAssembly.html#exports
    // Note: once we can set --shared this shouldn't be needed, since we set
    // default visibility on exported functions.
    for (auto func : exportedFuncs) {
      func->addFnAttr("wasm-export-name", func->getName());
    }

    return success();
  }

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

    // Create the wasm binary file 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, "wasm");
    } else {
      artifacts.libraryFile = Artifact::createTemporary(libraryName, "wasm");
    }
    artifacts.libraryFile.close();

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

        // Forces LLD to act like wasm ld and produce WebAssembly files.
        // If not specified then lld tries to figure out what it is by progname
        // (ld, ld64, link, etc).
        // NOTE: must be first because lld sniffs argv[1]/argv[2].
        "-flavor wasm",

        // entry symbol not defined (pass --no-entry to suppress): _start
        "--no-entry",

        // Treat warnings as errors.
        "--fatal-warnings",

        // Generated a shared object containing position-independent-code.
        "--experimental-pic",
        "--shared",

        // Import [shared] memory from the environment.
        // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory#creating_a_shared_memory
        // TODO(scotttodd): Add a flag controlling these - some combination is
        //   required when using multithreading + SharedArrayBuffer, but they
        //   must be left off when running single threaded.
        // "--import-memory",
        // "--shared-memory",

        "-o " + artifacts.libraryFile.path,
    };

    // Strip debug information when not requested.
    if (!targetOptions.target.debugSymbols) {
      flags.push_back("--strip-debug");
    }

    // 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;
    return artifacts;
  }
};

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

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