// 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/LLVMTargetOptions.h"

#include "compiler/plugins/target/LLVMCPU/ResolveCPUAndCPUFeatures.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/TargetParser/Host.h"
#include "llvm/TargetParser/Triple.h"
#include "mlir/IR/Builders.h"

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

LLVMTarget::LLVMTarget() {
  // LLVM loop optimization options.
  pipelineTuningOptions.LoopInterleaving = DEFAULT_LOOP_INTERLEAVING;
  pipelineTuningOptions.LoopVectorization = DEFAULT_LOOP_VECTORIZATION;
  pipelineTuningOptions.LoopUnrolling = DEFAULT_LOOP_UNROLLING;

  // LLVM SLP Auto vectorizer.
  pipelineTuningOptions.SLPVectorization = DEFAULT_SLP_VECTORIZATION;

  // LLVM optimization levels.
  // TODO(benvanik): add an option for this.
  optimizerOptLevel = llvm::OptimizationLevel::O2;
  codeGenOptLevel = llvm::CodeGenOptLevel::Aggressive;
  llvmTargetOptions.FloatABIType = DEFAULT_FLOAT_ABI;

  // Force `-ffunction-sections` so we can strip unused code.
  llvmTargetOptions.FunctionSections = true;
  llvmTargetOptions.DataSections = true;
  llvmTargetOptions.UniqueSectionNames = true;
}

std::optional<LLVMTarget>
LLVMTarget::create(std::string_view triple, std::string_view cpu,
                   std::string_view cpuFeatures, bool requestLinkEmbedded,
                   ResolveCPUAndCPUFeaturesStatus &status) {
  LLVMTarget target;
  target.linkEmbedded = requestLinkEmbedded;
  target.triple = (triple.empty() || triple == "host")
                      ? llvm::sys::getProcessTriple()
                      : triple;
  llvm::Triple targetTriple(target.triple);
  // Special casing if linkEmbedded.
  if (targetTriple.isWasm()) {
    // The embedded ELF loader is not supported on WebAssembly, so force it off.
    target.linkEmbedded = false;
  }
  if (target.linkEmbedded) {
    // Force the triple to something compatible with embedded linking.
    targetTriple.setVendor(llvm::Triple::VendorType::UnknownVendor);
    targetTriple.setEnvironment(llvm::Triple::EnvironmentType::EABI);
    targetTriple.setOS(llvm::Triple::OSType::UnknownOS);
    targetTriple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF);
  }
  target.triple = targetTriple.str();
  target.cpu = cpu;
  target.cpuFeatures = cpuFeatures;
  status = resolveCPUAndCPUFeatures(triple, target.cpu, target.cpuFeatures);
  return target;
}

std::optional<LLVMTarget> LLVMTarget::createForHost() {
  ResolveCPUAndCPUFeaturesStatus status;
  auto triple = llvm::sys::getProcessTriple();
  auto target = LLVMTarget::create(triple, /*cpu=*/"host",
                                   /*cpuFeatures=*/"host",
                                   /*requestLinkEmbedded=*/true, status);
  if (status != ResolveCPUAndCPUFeaturesStatus::OK) {
    llvm::errs() << "Internal error while creating host target: "
                 << getMessage(status, triple) << "\n";
    return std::nullopt;
  }
  if (target)
    target->populateDefaultsFromTargetMachine();
  return target;
}

void LLVMTarget::print(llvm::raw_ostream &os) const {
  os << "LLVMTarget{\n"
     << "  triple=" << triple << ", cpu=" << cpu
     << ", cpuFeatures=" << cpuFeatures << "\n"
     << "  dataLayout=" << dataLayout << "\n"
     << "  vectorWidthInBytes=" << vectorWidthInBytes << "\n"
     << "  linkEmbedded=" << linkEmbedded << "\n"
     << "  debugSymbols=" << debugSymbols << "\n"
     << "  sanitizer=" << static_cast<int>(sanitizerKind) << "\n"
     << "  staticLibraryOutput=" << staticLibraryOutput << "\n"
     << "  linkStatic=" << linkStatic << "\n"
     << "  pipelineTuningOptions={\n"
     << "    LoopInterleaving=" << pipelineTuningOptions.LoopInterleaving
     << "\n"
     << "    LoopVectorization=" << pipelineTuningOptions.LoopVectorization
     << "\n"
     << "    LoopUnrolling=" << pipelineTuningOptions.LoopUnrolling << "\n"
     << "    SLPVectorization=" << pipelineTuningOptions.SLPVectorization
     << "\n"
     << "  }, llvmTargetOptions={\n"
     << "    FloatABIType=" << static_cast<int>(llvmTargetOptions.FloatABIType)
     << "\n"
     << "  }\n"
     << "  ukernels=" << ukernels << "\n"
     << "  linkUkernelBitcode=" << linkUkernelBitcode << "\n"
     << "}\n";
}

void LLVMTarget::storeToConfigAttrs(MLIRContext *context,
                                    SmallVector<NamedAttribute> &config) const {
  Builder b(context);
  auto addString = [&](StringRef name, StringRef value) {
    config.emplace_back(b.getStringAttr(name), b.getStringAttr(value));
  };
  auto addBool = [&](StringRef name, bool value) {
    config.emplace_back(b.getStringAttr(name), b.getBoolAttr(value));
  };
  auto addInt64 = [&](StringRef name, int64_t value) {
    config.emplace_back(b.getStringAttr(name), b.getI64IntegerAttr(value));
  };

  addString("target_triple", triple);
  addString("cpu", cpu);
  addString("cpu_features", cpuFeatures);
  if (!dataLayout.empty()) {
    addString("data_layout", dataLayout);
  }
  if (vectorWidthInBytes != DEFAULT_VECTOR_WIDTH_IN_BYTES) {
    addInt64("native_vector_size", vectorWidthInBytes);
  }
  if (linkEmbedded != DEFAULT_LINK_EMBEDDED) {
    addBool("link_embedded", linkEmbedded);
  }
  if (debugSymbols != DEFAULT_DEBUG_SYMBOLS) {
    addBool("debug_symbols", debugSymbols);
  }
  if (linkStatic != DEFAULT_LINK_STATIC) {
    addBool("link_static", linkStatic);
  }
  if (sanitizerKind != DEFAULT_SANITIZER_KIND) {
    switch (sanitizerKind) {
    case SanitizerKind::kNone:
      addString("sanitizer", "none");
      break;
    case SanitizerKind::kAddress:
      addString("sanitizer", "address");
      break;
    case SanitizerKind::kThread:
      addString("sanitizer", "thread");
      break;
    }
  }
  if (!staticLibraryOutput.empty()) {
    addString("static_library_output", staticLibraryOutput);
  }
  if (pipelineTuningOptions.LoopInterleaving != DEFAULT_LOOP_INTERLEAVING)
    addBool("loop_interleaving", pipelineTuningOptions.LoopInterleaving);
  if (pipelineTuningOptions.LoopVectorization != DEFAULT_LOOP_VECTORIZATION)
    addBool("loop_vectorization", pipelineTuningOptions.LoopVectorization);
  if (pipelineTuningOptions.LoopUnrolling != DEFAULT_LOOP_UNROLLING)
    addBool("loop_unrolling", pipelineTuningOptions.LoopUnrolling);
  if (pipelineTuningOptions.SLPVectorization != DEFAULT_SLP_VECTORIZATION)
    addBool("slp_vectorization", pipelineTuningOptions.SLPVectorization);
  if (!llvmTargetOptions.MCOptions.ABIName.empty())
    addString("target_abi", llvmTargetOptions.MCOptions.ABIName);
  if (llvmTargetOptions.FloatABIType != DEFAULT_FLOAT_ABI) {
    switch (llvmTargetOptions.FloatABIType) {
    case llvm::FloatABI::Default:
      addString("float_abi", "default");
      break;
    case llvm::FloatABI::Soft:
      addString("float_abi", "soft");
      break;
    case llvm::FloatABI::Hard:
      addString("float_abi", "hard");
      break;
    }
  }
  if (ukernels.compare(DEFAULT_ENABLE_UKERNELS) != 0)
    addString("ukernels", ukernels);
  if (linkUkernelBitcode != DEFAULT_LINK_UKERNEL_BITCODE)
    addBool("link_ukernel_bitcode", linkUkernelBitcode);
}

std::optional<LLVMTarget>
LLVMTarget::loadFromConfigAttr(Location loc, DictionaryAttr config,
                               const LLVMTarget &defaultTarget) {
  bool hasFailures = false;
  auto getString = [&](StringRef name, StringRef fallback,
                       bool required) -> StringRef {
    Attribute attr = config.get(name);
    if (auto sattr = llvm::dyn_cast_if_present<StringAttr>(attr)) {
      return sattr.strref();
    } else {
      if (required) {
        hasFailures = true;
        emitError(loc) << "executable config '" << name
                       << "' required but not present on attribute";
      }
      return fallback;
    }
  };
  auto getOptionalString = [&](StringRef name) -> std::optional<StringRef> {
    Attribute attr = config.get(name);
    if (auto sattr = llvm::dyn_cast_if_present<StringAttr>(attr)) {
      return sattr.strref();
    } else if (attr) {
      hasFailures = true;
      emitError(loc) << "executable config '" << name
                     << "' requires string but got " << attr;
    }
    return {};
  };
  auto getBool = [&](StringRef name, bool fallback) -> bool {
    Attribute attr = config.get(name);
    if (auto battr = llvm::dyn_cast_if_present<BoolAttr>(attr)) {
      return battr.getValue();
    } else if (attr) {
      hasFailures = true;
      emitError(loc) << "executable config '" << name
                     << "' requires bool but got " << attr;
    }
    return fallback;
  };
  auto getInt64 = [&](StringRef name, int64_t fallback) -> int64_t {
    Attribute attr = config.get(name);
    if (auto iattr = llvm::dyn_cast_if_present<IntegerAttr>(attr)) {
      return iattr.getValue().getSExtValue();
    } else if (attr) {
      hasFailures = true;
      emitError(loc) << "executable config '" << name
                     << "' requires i64 but got " << attr;
    }
    return fallback;
  };

  LLVMTarget target;

  // Constructor arguments.
  auto triple = getOptionalString("target_triple");
  auto cpu = getOptionalString("cpu");
  auto cpuFeatures = getOptionalString("cpu_features");
  bool linkEmbedded = getBool("link_embedded", DEFAULT_LINK_EMBEDDED);
  if (triple || cpu || cpuFeatures) {
    if (!triple) {
      emitError(loc) << "executable config 'cpu' or 'cpu_features' must be "
                        "accompanied by 'target_triple'";
      return {};
    }
    ResolveCPUAndCPUFeaturesStatus status;
    std::optional<LLVMTarget> maybeTarget =
        LLVMTarget::create(*triple, cpu.value_or(""), cpuFeatures.value_or(""),
                           linkEmbedded, status);
    if (status != ResolveCPUAndCPUFeaturesStatus::OK) {
      // TODO(#18561): after people have had time to adapt, typically by adding
      // --iree-llvmcpu-target-cpu=generic (or another value) to their invokes,
      // promote this warning to an error by changing emitWarning to emitError
      // and nulling maybeTarget.
      emitWarning(loc) << "while creating CPU target: "
                       << getMessage(status, *triple);
    }
    if (!maybeTarget) {
      return {};
    }
    target.copy(*maybeTarget);
  } else {
    target.copy(defaultTarget);
  }

  target.dataLayout = getString("data_layout", DEFAULT_DATA_LAYOUT, false);
  target.vectorWidthInBytes =
      getInt64("native_vector_size", DEFAULT_VECTOR_WIDTH_IN_BYTES);

  target.debugSymbols = getBool("debug_symbols", DEFAULT_DEBUG_SYMBOLS);
  target.linkStatic = getBool("link_static", DEFAULT_LINK_STATIC);
  auto sanitizer = getOptionalString("sanitizer");
  if (sanitizer) {
    if (sanitizer == "none")
      target.sanitizerKind = SanitizerKind::kNone;
    else if (sanitizer == "address")
      target.sanitizerKind = SanitizerKind::kAddress;
    else if (sanitizer == "thread")
      target.sanitizerKind = SanitizerKind::kThread;
    else {
      emitError(loc) << "executable config unexpected value for 'sanitizer': "
                     << *sanitizer;
      return {};
    }
  }
  target.staticLibraryOutput = getString("static_library_output", "", false);

  target.pipelineTuningOptions.LoopInterleaving = getBool(
      "loop_interleaving", target.pipelineTuningOptions.LoopInterleaving);
  target.pipelineTuningOptions.LoopVectorization = getBool(
      "loop_vectorization", target.pipelineTuningOptions.LoopVectorization);
  target.pipelineTuningOptions.LoopUnrolling =
      getBool("loop_unrolling", target.pipelineTuningOptions.LoopUnrolling);
  target.pipelineTuningOptions.SLPVectorization = getBool(
      "slp_vectorization", target.pipelineTuningOptions.SLPVectorization);
  auto targetAbi = getOptionalString("target_abi");
  if (targetAbi)
    target.llvmTargetOptions.MCOptions.ABIName = *targetAbi;
  auto floatAbi = getOptionalString("float_abi");
  if (floatAbi) {
    if (floatAbi == "default")
      target.llvmTargetOptions.FloatABIType = llvm::FloatABI::Default;
    else if (floatAbi == "soft")
      target.llvmTargetOptions.FloatABIType = llvm::FloatABI::Default;
    else if (floatAbi == "hard")
      target.llvmTargetOptions.FloatABIType = llvm::FloatABI::Default;
    else {
      emitError(loc) << "executable config unexpected value for 'float_abi'";
      return {};
    }
  }

  target.ukernels = getString("ukernels", target.ukernels, false);
  target.linkUkernelBitcode =
      getBool("link_ukernel_bitcode", target.linkUkernelBitcode);

  if (hasFailures) {
    return {};
  }
  target.populateDefaultsFromTargetMachine();
  return target;
}

void LLVMTarget::populateDefaultsFromTargetMachine() {
  // We may need the target machine for certain default values.
  std::unique_ptr<llvm::TargetMachine> cachedTargetMachine;
  auto getTargetMachine = [&]() {
    if (!cachedTargetMachine) {
      cachedTargetMachine = createTargetMachine(*this);
      // TODO(#13988): proper error propagation. This is a common user scenario.
      assert(cachedTargetMachine && "createTargetMachine failed");
    }
    return cachedTargetMachine.get();
  };

  if (dataLayout.empty()) {
    auto targetDataLayout = getTargetMachine()->createDataLayout();
    dataLayout = targetDataLayout.getStringRepresentation();
  }

  if (vectorWidthInBytes == DEFAULT_VECTOR_WIDTH_IN_BYTES) {
    auto targetMachine = getTargetMachine();
    auto targetFeatures = targetMachine->getTargetFeatureString();

    // The only way to get the real TTI is to create a function using it.
    // LLVM's TargetMachine and related APIs are terrible. Absolutely yuck.
    // Note that we use the data layout set above to either what the user
    // specified or what the target machine returned.
    //
    // If anyone comes across this: it'd be great if getTargetTransformInfo
    // could be called without requiring a function.
    llvm::LLVMContext llvmContext;
    auto llvmModule =
        std::make_unique<llvm::Module>("dummy_module", llvmContext);
    llvmModule->setDataLayout(dataLayout);
    llvm::Function *dummyFunc = llvm::Function::Create(
        llvm::FunctionType::get(llvm::Type::getVoidTy(llvmContext), false),
        llvm::GlobalValue::ExternalLinkage, "dummy_func", *llvmModule);
    if (targetFeatures.contains("avx512")) {
      // Always override the vector with to 512 on systems with avx512.
      // @dcaballe says:
      // > in ML the frequency throttling that happens when using 512-bit
      // > register doesn't have an overall negative impact in performance due
      // > to the high computational density of the workloads, even on skylake
      // > where the throttling was really bad
      dummyFunc->addFnAttr("prefer-vector-width", "512");
    }
    auto targetTTI = targetMachine->getTargetTransformInfo(*dummyFunc);

    // Query the vector width from TTI.
    unsigned ttiVectorWidthInBytes =
        targetTTI.getRegisterBitWidth(
            llvm::TargetTransformInfo::RGK_FixedWidthVector) /
        8;
    vectorWidthInBytes = ttiVectorWidthInBytes > 1 ? ttiVectorWidthInBytes : 16;
  }
}

std::unique_ptr<llvm::TargetMachine>
createTargetMachine(const LLVMTarget &target) {
  std::string errorMessage;
  auto llvmTarget =
      llvm::TargetRegistry::lookupTarget(target.getTriple(), errorMessage);
  if (!llvmTarget)
    return nullptr;
  std::unique_ptr<llvm::TargetMachine> machine(llvmTarget->createTargetMachine(
      target.getTriple(), target.getCpu() /* cpu e.g k8 */,
      target.getCpuFeatures() /* cpu features e.g avx512f */,
      target.llvmTargetOptions, llvm::Reloc::Model::PIC_, {},
      target.codeGenOptLevel,
      /*JIT=*/false));
  return machine;
}

static void initializeLLVMTargets() {
// Dynamically do preprocessor dispatch to initialize only targets that we
// care about if they are enabled. Unfortunately, the way the LLVM macros
// for this are set up and the inability to do a conditional within a macro
// means that we have to syntactically have a macro for every possible
// target we care about. There are more robust ways to do this but they all
// require build support, which is a pain to manage across platforms.
//
// See comments below.
#define LLVM_INITIALIZE_GENERIC(TargetName)                                    \
  LLVMInitialize##TargetName##Target();                                        \
  LLVMInitialize##TargetName##TargetMC();                                      \
  LLVMInitialize##TargetName##TargetInfo();                                    \
  LLVMInitialize##TargetName##AsmPrinter();                                    \
  LLVMInitialize##TargetName##AsmParser();

// CPU targets that we care about and have hard-linked against are here.
// They delegate to the generic initialize above. These must all be added
// to the build file or you will get undefined symbol errors at link time.
#define LLVM_INITIALIZE_TARGET_AArch64() LLVM_INITIALIZE_GENERIC(AArch64)
#define LLVM_INITIALIZE_TARGET_ARM() LLVM_INITIALIZE_GENERIC(ARM)
#define LLVM_INITIALIZE_TARGET_RISCV() LLVM_INITIALIZE_GENERIC(RISCV)
#define LLVM_INITIALIZE_TARGET_X86() LLVM_INITIALIZE_GENERIC(X86)
#define LLVM_INITIALIZE_TARGET_WebAssembly()                                   \
  LLVM_INITIALIZE_GENERIC(WebAssembly)

// We must no-op the name of each target we don't care about. This is annoying,
// but targets aren't created every day and isn't the end of the world. The
// error messages when missing are quite clear and you just add a line here.
#define LLVM_INITIALIZE_TARGET_AMDGPU()
#define LLVM_INITIALIZE_TARGET_AVR()
#define LLVM_INITIALIZE_TARGET_BPF()
#define LLVM_INITIALIZE_TARGET_Hexagon()
#define LLVM_INITIALIZE_TARGET_Lanai()
#define LLVM_INITIALIZE_TARGET_LoongArch()
#define LLVM_INITIALIZE_TARGET_Mips()
#define LLVM_INITIALIZE_TARGET_MSP430()
#define LLVM_INITIALIZE_TARGET_NVPTX()
#define LLVM_INITIALIZE_TARGET_PowerPC()
#define LLVM_INITIALIZE_TARGET_Sparc()
#define LLVM_INITIALIZE_TARGET_SystemZ()
#define LLVM_INITIALIZE_TARGET_VE()
#define LLVM_INITIALIZE_TARGET_XCore()

#define LLVM_TARGET(TargetName) LLVM_INITIALIZE_TARGET_##TargetName()
#include "llvm/Config/Targets.def"
}

//===----------------------------------------------------------------------===//
//    __    __   ___________    ____     ____    ____  ______    __    __     //
//   |  |  |  | |   ____\   \  /   /     \   \  /   / /  __  \  |  |  |  |    //
//   |  |__|  | |  |__   \   \/   /       \   \/   / |  |  |  | |  |  |  |    //
//   |   __   | |   __|   \_    _/         \_    _/  |  |  |  | |  |  |  |    //
//   |  |  |  | |  |____    |  |   __        |  |    |  `--'  | |  `--'  |    //
//   |__|  |__| |_______|   |__|  (_ )       |__|     \______/   \______/     //
//                                 |/                                         //
//===----------------------------------------------------------------------===//
//
// Beware adding command-line flags here: IREE is a cross-compiler and can
// compile for multiple targets in a single invocation. Global flags added here
// apply to all targets with no way to override them from hosting applications
// that may need to programmatically set them per target and that's bad.
//
// Flags *must* be added to the LLVMTarget if they are target-specific and
// LLVMTargetOptions if they are apply to the whole backend.

void LLVMCPUTargetCLOptions::bindOptions(OptionsBinder &binder) {
  // Initialize LLVM targets prior to the iree-llvmcpu-list-targets CLI opt.
  initializeLLVMTargets();

  static llvm::cl::OptionCategory category("LLVMCPU HAL Target");

  // General flags.
  binder.opt<bool>(
      "iree-llvmcpu-list-targets", listTargets, llvm::cl::cat(category),
      llvm::cl::desc("Lists all registered targets that the LLVM backend can "
                     "generate code for."),
      llvm::cl::ValueDisallowed, llvm::cl::callback([&](const bool &) {
        llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
        exit(0);
      }));

  // Target invariant flags.
  binder.opt<std::string>(
      "iree-llvmcpu-system-linker-path", systemLinkerPath,
      llvm::cl::cat(category),
      llvm::cl::desc("Tool used to link system shared libraries produced by "
                     "IREE (for --iree-llvmcpu-link-embedded=false)."));
  binder.opt<std::string>(
      "iree-llvmcpu-embedded-linker-path", embeddedLinkerPath,
      llvm::cl::cat(category),
      llvm::cl::desc("Tool used to link embedded ELFs produced by IREE (for "
                     "--iree-llvmcpu-link-embedded=true)."));
  binder.opt<std::string>(
      "iree-llvmcpu-wasm-linker-path", wasmLinkerPath, llvm::cl::cat(category),
      llvm::cl::desc("Tool used to link WebAssembly modules produced by "
                     "IREE (for --iree-llvmcpu-target-triple=wasm32-*)."));
  binder.opt<bool>(
      "iree-llvmcpu-keep-linker-artifacts", keepLinkerArtifacts,
      llvm::cl::cat(category),
      llvm::cl::desc("Keep LLVM linker target artifacts (.so/.dll/etc)"));

  // Default device options.
  binder.opt<std::string>("iree-llvmcpu-target-triple", targetTriple,
                          llvm::cl::cat(category),
                          llvm::cl::desc("LLVM target machine triple."));
  binder.opt<std::string>(
      "iree-llvmcpu-target-cpu", targetCPU, llvm::cl::cat(category),
      llvm::cl::desc(
          "LLVM target machine CPU; use 'host' for your host native CPU."));
  binder.opt<std::string>(
      "iree-llvmcpu-target-cpu-features", targetCPUFeatures,
      llvm::cl::cat(category),
      llvm::cl::desc("LLVM target machine CPU features; use 'host' for your "
                     "host native CPU."));
  binder.opt<bool>(
      "iree-llvmcpu-link-embedded", linkEmbedded, llvm::cl::cat(category),
      llvm::cl::desc("Links binaries into a platform-agnostic ELF to be "
                     "loaded by the embedded IREE ELF loader."));
  binder.opt<bool>(
      "iree-llvmcpu-link-static", linkStatic, llvm::cl::cat(category),
      llvm::cl::desc(
          "Links system libraries into binaries statically to isolate them "
          "from platform dependencies needed at runtime"));
  binder.opt<std::string>(
      "iree-llvmcpu-static-library-output-path", staticLibraryOutputPath,
      llvm::cl::cat(category),
      llvm::cl::desc(
          "Path to output static object (EX: '/path/to/static-library.o'). "
          "This will produce the static library at the specified path along "
          "with a similarly named '.h' file for static linking."));
  binder.opt<bool>(
      "iree-llvmcpu-debug-symbols", debugSymbols, llvm::cl::cat(category),
      llvm::cl::desc("Generate and embed debug information (DWARF, PDB, etc)"));
  binder.opt<bool>("iree-llvmcpu-loop-interleaving", llvmLoopInterleaving,
                   llvm::cl::cat(category),
                   llvm::cl::desc("Enable LLVM loop interleaving opt"));
  binder.opt<bool>("iree-llvmcpu-loop-vectorization", llvmLoopVectorization,
                   llvm::cl::cat(category),
                   llvm::cl::desc("Enable LLVM loop vectorization opt"));
  binder.opt<bool>("iree-llvmcpu-loop-unrolling", llvmLoopUnrolling,
                   llvm::cl::cat(category),
                   llvm::cl::desc("Enable LLVM loop unrolling opt"));
  binder.opt<bool>("iree-llvmcpu-slp-vectorization", llvmSLPVectorization,
                   llvm::cl::cat(category),
                   llvm::cl::desc("Enable LLVM SLP Vectorization opt"));
  binder.opt<SanitizerKind>(
      "iree-llvmcpu-sanitize", sanitizerKind, llvm::cl::cat(category),
      llvm::cl::desc("Apply LLVM sanitize feature"),
      llvm::cl::values(clEnumValN(SanitizerKind::kAddress, "address",
                                  "Address sanitizer support"),
                       clEnumValN(SanitizerKind::kThread, "thread",
                                  "Thread sanitizer support")));
  binder.opt<std::string>(
      "iree-llvmcpu-target-abi", targetABI, llvm::cl::cat(category),
      llvm::cl::desc("LLVM target machine ABI; specify for -mabi"));
  binder.opt<llvm::FloatABI::ABIType>(
      "iree-llvmcpu-target-float-abi", targetFloatABI, llvm::cl::cat(category),
      llvm::cl::desc("LLVM target codegen enables soft float abi e.g "
                     "-mfloat-abi=softfp"),
      llvm::cl::values(
          clEnumValN(llvm::FloatABI::Default, "default", "Default (softfp)"),
          clEnumValN(llvm::FloatABI::Soft, "soft",
                     "Software floating-point emulation"),
          clEnumValN(llvm::FloatABI::Hard, "hard",
                     "Hardware floating-point instructions")));
  binder.opt<std::string>(
      "iree-llvmcpu-target-data-layout", targetDataLayout,
      llvm::cl::cat(category),
      llvm::cl::desc("LLVM target machine data layout override."));
  binder.opt<unsigned>("iree-llvmcpu-target-vector-width-in-bytes",
                       targetVectorWidthInBytes, llvm::cl::cat(category),
                       llvm::cl::desc("Overrides the native vector register "
                                      "width (in bytes) of the target."));
  binder.opt<std::string>(
      "iree-llvmcpu-enable-ukernels", enableUkernels, llvm::cl::cat(category),
      llvm::cl::desc("Enables ukernels in the llvmcpu backend. May be "
                     "`default`, `none`, `all`, or a comma-separated list of "
                     "specific unprefixed ukernels to enable, e.g. `mmt4d`."));
  binder.opt<bool>(
      "iree-llvmcpu-link-ukernel-bitcode", linkUKernelBitcode,
      llvm::cl::cat(category),
      llvm::cl::desc(
          "Link ukernel bitcode libraries into generated executables"));
}

LLVMTargetOptions LLVMCPUTargetCLOptions::getTargetOptions() {
  LLVMTargetOptions targetOptions;
  targetOptions.systemLinkerPath = systemLinkerPath;
  targetOptions.embeddedLinkerPath = embeddedLinkerPath;
  targetOptions.wasmLinkerPath = wasmLinkerPath;
  targetOptions.keepLinkerArtifacts = keepLinkerArtifacts;

  if (targetTriple.empty()) {
    targetTriple = llvm::sys::getProcessTriple();
  }

  ResolveCPUAndCPUFeaturesStatus status;
  std::optional<LLVMTarget> maybeTarget = LLVMTarget::create(
      targetTriple, targetCPU, targetCPUFeatures, linkEmbedded, status);
  (void)status; // Ignore status here, since this code runs at target backend
                // registration time and we don't know if this backend will
                // actually be used, and these error statuses are non-fatal,
                // mostly warning about fallbacks. If the target backend is
                // actually used, any error here will also trigger in
                // loadFromConfigAttr, where we will generate an IR error.
  if (maybeTarget) {
    targetOptions.target = *maybeTarget;
  } else {
    llvm::errs() << "The target CPU is not properly defined.\n";
  }
  LLVMTarget &target = targetOptions.target;
  target.linkStatic = linkStatic;
  target.staticLibraryOutput = staticLibraryOutputPath;
  target.debugSymbols = debugSymbols;
  target.pipelineTuningOptions.LoopInterleaving = llvmLoopInterleaving;
  target.pipelineTuningOptions.LoopVectorization = llvmLoopVectorization;
  target.pipelineTuningOptions.LoopUnrolling = llvmLoopUnrolling;
  target.pipelineTuningOptions.SLPVectorization = llvmSLPVectorization;
  target.sanitizerKind = sanitizerKind;
  target.llvmTargetOptions.MCOptions.ABIName = targetABI;
  target.llvmTargetOptions.FloatABIType = targetFloatABI;
  target.dataLayout = targetDataLayout;
  target.vectorWidthInBytes = targetVectorWidthInBytes;
  target.ukernels = enableUkernels;
  target.linkUkernelBitcode = linkUKernelBitcode;

  target.populateDefaultsFromTargetMachine();
  return targetOptions;
}

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