// Copyright 2023 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 "iree/compiler/PluginAPI/Client.h"
#include "mlir/Conversion/Passes.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/Pass/PassManager.h"
#include "stablehlo/dialect/ChloOps.h"
#include "stablehlo/dialect/StablehloOps.h"

#include "stablehlo-iree/Conversion/Passes.h"

namespace mlir::iree_compiler::stablehlo {

namespace {

struct StableHLOOptions {
  bool demoteI64ToI32 = true;
  bool demoteF64ToF32 = false;
  bool promoteBF16ToF32 = false;

  void bindOptions(OptionsBinder &binder) {
    static llvm::cl::OptionCategory category("StableHLO Input");

    // TODO(#8745): Find a better place for these options / rename them
    //     * Could rename to 'iree-stablehlo-*', but would want to update users
    //     * Could make generic, if they can be used with other dialects
    binder.opt<bool>(
        "iree-input-demote-i64-to-i32", demoteI64ToI32,
        llvm::cl::desc(
            "Converts all i64 ops and values into i32 counterparts."),
        llvm::cl::cat(category));

    binder.opt<bool>(
        "iree-input-demote-f64-to-f32", demoteF64ToF32,
        llvm::cl::desc(
            "Converts all f64 ops and values into f32 counterparts."),
        llvm::cl::cat(category));

    binder.opt<bool>(
        "iree-input-promote-bf16-to-f32", promoteBF16ToF32,
        llvm::cl::desc(
            "Converts all bf16 ops and values into f32 counterparts."),
        llvm::cl::cat(category));
  }
};

static bool checkOpForTuples(Operation *op) {
  if (auto funcOp = dyn_cast<func::FuncOp>(op)) {
    FunctionType type = dyn_cast<FunctionType>(funcOp.getFunctionType());
    for (auto t : type.getResults()) {
      if (isa<TupleType>(t)) {
        return true;
      }
    }
    for (auto t : type.getInputs()) {
      if (isa<TupleType>(t)) {
        return true;
      }
    }
  }

  // Check for tuple operands or results.
  for (auto t : op->getOperandTypes()) {
    if (isa<TupleType>(t)) {
      return true;
    }
  }
  for (auto t : op->getResultTypes()) {
    if (isa<TupleType>(t)) {
      return true;
    }
  }

  return false;
}

// StableHLO (https://github.com/openxla/stablehlo) support plugin.
//
// The StableHLO plugin provides dialects, passes and opt-in options.
// Therefore, it is appropriate for default activation.
struct StableHLOSession
    : public PluginSession<StableHLOSession, StableHLOOptions,
                           PluginActivationPolicy::DefaultActivated> {
  static void registerPasses() {
    // TODO(scotttodd): register other StableHLO passes?
    registerStableHLOConversionPasses();
  }

  void onRegisterDialects(DialectRegistry &registry) override {
    registry.insert<mlir::chlo::ChloDialect>();
    registry.insert<mlir::stablehlo::StablehloDialect>();
  }

  bool extendCustomInputConversionPassPipeline(
      OpPassManager &passManager, std::string_view typeMnemonic) override {
    StableHloOptions stableHloOptions;
    stableHloOptions.demoteI64ToI32 = options.demoteI64ToI32;
    stableHloOptions.demoteF64ToF32 = options.demoteF64ToF32;
    stableHloOptions.promoteBF16ToF32 = options.promoteBF16ToF32;

    if (typeMnemonic == "stablehlo") {
      buildStableHLOInputConversionPassPipeline(passManager, stableHloOptions);
      return true;
    } else if (typeMnemonic == "stablehlo_xla") {
      buildStableHLOXLAInputConversionPassPipeline(passManager,
                                                   stableHloOptions);
      return true;
    }

    return false;
  }

  void populateCustomInputConversionTypes(StringSet<> &typeMnemonics) override {
    typeMnemonics.insert("stablehlo");
    typeMnemonics.insert("stablehlo_xla");
  }

  void populateDetectedCustomInputConversionTypes(
      ModuleOp &module, StringSet<> &typeMnemonics) override {

    auto *ctx = module.getContext();
    const Dialect *chloDialect = ctx->getLoadedDialect("chlo");
    const Dialect *stablehloDialect = ctx->getLoadedDialect("stablehlo");

    // stablehlo ops _with tuples_    --> only "stablehlo_xla" type
    // stablehlo ops _without tuples_ --> only "stablehlo" type
    // no stablehlo ops --> no types

    bool hasStableHLO = false;
    bool hasTuples = false;
    module.walk([&](Operation *op) {
      Dialect *d = op->getDialect();
      if (d == chloDialect || d == stablehloDialect) {
        hasStableHLO = true;
        if (checkOpForTuples(op)) {
          hasTuples = true;
          // Early exit, no need to continue scanning.
          return WalkResult::interrupt();
        }
        // Keep scanning in case a future op contains tuples.
      }
      return WalkResult::advance();
    });

    if (hasTuples) {
      typeMnemonics.insert("stablehlo_xla");
    } else if (hasStableHLO) {
      typeMnemonics.insert("stablehlo");
    }
  }
};

} // namespace

} // namespace mlir::iree_compiler::stablehlo

IREE_DEFINE_COMPILER_OPTION_FLAGS(
    ::mlir::iree_compiler::stablehlo::StableHLOOptions);

extern "C" bool iree_register_compiler_plugin_input_stablehlo(
    mlir::iree_compiler::PluginRegistrar *registrar) {
  registrar->registerPlugin<::mlir::iree_compiler::stablehlo::StableHLOSession>(
      "input_stablehlo");
  return true;
}
