//===- GPUToLLVMSPV.cpp - Convert GPU operations to LLVM dialect ----------===//
//
// Part of the LLVM Project, 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 "mlir/Conversion/GPUToLLVMSPV/GPUToLLVMSPVPass.h"

#include "../GPUCommon/GPUOpsLowering.h"
#include "mlir/Conversion/GPUCommon/AttrToSPIRVConverter.h"
#include "mlir/Conversion/GPUCommon/GPUCommonPass.h"
#include "mlir/Conversion/LLVMCommon/ConversionTarget.h"
#include "mlir/Conversion/LLVMCommon/LoweringOptions.h"
#include "mlir/Conversion/LLVMCommon/Pattern.h"
#include "mlir/Conversion/LLVMCommon/TypeConverter.h"
#include "mlir/Conversion/SPIRVCommon/AttrToLLVMConverter.h"
#include "mlir/Dialect/GPU/IR/GPUDialect.h"
#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
#include "mlir/Dialect/SPIRV/IR/SPIRVEnums.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Matchers.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/IR/SymbolTable.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Support/LLVM.h"
#include "mlir/Transforms/DialectConversion.h"

#include "llvm/ADT/TypeSwitch.h"
#include "llvm/Support/FormatVariadic.h"

#define DEBUG_TYPE "gpu-to-llvm-spv"

using namespace mlir;

namespace mlir {
#define GEN_PASS_DEF_CONVERTGPUOPSTOLLVMSPVOPS
#include "mlir/Conversion/Passes.h.inc"
} // namespace mlir

//===----------------------------------------------------------------------===//
// Helper Functions
//===----------------------------------------------------------------------===//

static LLVM::LLVMFuncOp lookupOrCreateSPIRVFn(Operation *symbolTable,
                                              StringRef name,
                                              ArrayRef<Type> paramTypes,
                                              Type resultType, bool isMemNone,
                                              bool isConvergent) {
  auto func = dyn_cast_or_null<LLVM::LLVMFuncOp>(
      SymbolTable::lookupSymbolIn(symbolTable, name));
  if (!func) {
    OpBuilder b(symbolTable->getRegion(0));
    func = LLVM::LLVMFuncOp::create(
        b, symbolTable->getLoc(), name,
        LLVM::LLVMFunctionType::get(resultType, paramTypes));
    func.setCConv(LLVM::cconv::CConv::SPIR_FUNC);
    func.setNoUnwind(true);
    func.setWillReturn(true);

    if (isMemNone) {
      // no externally observable effects
      constexpr auto noModRef = mlir::LLVM::ModRefInfo::NoModRef;
      auto memAttr = b.getAttr<LLVM::MemoryEffectsAttr>(
          /*other=*/noModRef,
          /*argMem=*/noModRef, /*inaccessibleMem=*/noModRef,
          /*errnoMem=*/noModRef,
          /*targetMem0=*/noModRef,
          /*targetMem1=*/noModRef);
      func.setMemoryEffectsAttr(memAttr);
    }

    func.setConvergent(isConvergent);
  }
  return func;
}

static LLVM::CallOp createSPIRVBuiltinCall(Location loc,
                                           ConversionPatternRewriter &rewriter,
                                           LLVM::LLVMFuncOp func,
                                           ValueRange args) {
  auto call = LLVM::CallOp::create(rewriter, loc, func, args);
  call.setCConv(func.getCConv());
  call.setConvergentAttr(func.getConvergentAttr());
  call.setNoUnwindAttr(func.getNoUnwindAttr());
  call.setWillReturnAttr(func.getWillReturnAttr());
  call.setMemoryEffectsAttr(func.getMemoryEffectsAttr());
  return call;
}

namespace {
//===----------------------------------------------------------------------===//
// Barriers
//===----------------------------------------------------------------------===//

/// Replace `gpu.barrier` with an `llvm.call` to `barrier` using
/// `CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE`, ensuring that all memory
/// accesses are visible to all work-items in the work-group.
/// ```
/// // gpu.barrier
/// // 3 = CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE
/// %c3 = llvm.mlir.constant(3: i32) : i32
/// llvm.call spir_funccc @_Z7barrierj(%c3) : (i32) -> ()
/// ```
struct GPUBarrierConversion final : ConvertOpToLLVMPattern<gpu::BarrierOp> {
  using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern;

  LogicalResult
  matchAndRewrite(gpu::BarrierOp op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const final {
    constexpr StringLiteral funcName = "_Z7barrierj";

    Operation *moduleOp = op->getParentWithTrait<OpTrait::SymbolTable>();
    assert(moduleOp && "Expecting module");
    Type flagTy = rewriter.getI32Type();
    Type voidTy = rewriter.getType<LLVM::LLVMVoidType>();
    LLVM::LLVMFuncOp func =
        lookupOrCreateSPIRVFn(moduleOp, funcName, flagTy, voidTy,
                              /*isMemNone=*/false, /*isConvergent=*/true);

    // Values used by SPIR-V backend to represent `CLK_LOCAL_MEM_FENCE` and
    // `CLK_GLOBAL_MEM_FENCE`. See `llvm/lib/Target/SPIRV/SPIRVBuiltins.td`.
    constexpr int64_t localMemFenceFlag = 1;
    constexpr int64_t globalMemFenceFlag = 2;
    int64_t memFenceFlag = 0;
    std::optional<ArrayAttr> addressSpaces = adaptor.getAddressSpaces();
    if (addressSpaces) {
      for (Attribute attr : addressSpaces.value()) {
        auto addressSpace = cast<gpu::AddressSpaceAttr>(attr).getValue();
        switch (addressSpace) {
        case gpu::AddressSpace::Global:
          memFenceFlag = memFenceFlag | globalMemFenceFlag;
          break;
        case gpu::AddressSpace::Workgroup:
          memFenceFlag = memFenceFlag | localMemFenceFlag;
          break;
        case gpu::AddressSpace::Private:
        case gpu::AddressSpace::Constant:
          // Private is thread-local, constant is read-only; no fencing needed.
          break;
        }
      }
    } else {
      memFenceFlag = localMemFenceFlag | globalMemFenceFlag;
    }
    Location loc = op->getLoc();
    Value flag = LLVM::ConstantOp::create(rewriter, loc, flagTy, memFenceFlag);
    rewriter.replaceOp(op, createSPIRVBuiltinCall(loc, rewriter, func, flag));
    return success();
  }
};

//===----------------------------------------------------------------------===//
// SPIR-V Builtins
//===----------------------------------------------------------------------===//

/// Replace `gpu.*` with an `llvm.call` to the corresponding SPIR-V builtin with
/// a constant argument for the `dimension` attribute. Return type will depend
/// on index width option:
/// ```
/// // %thread_id_y = gpu.thread_id y
/// %c1 = llvm.mlir.constant(1: i32) : i32
/// %0 = llvm.call spir_funccc @_Z12get_local_idj(%c1) : (i32) -> i64
/// ```
struct LaunchConfigConversion : ConvertToLLVMPattern {
  LaunchConfigConversion(StringRef funcName, StringRef rootOpName,
                         MLIRContext *context,
                         const LLVMTypeConverter &typeConverter,
                         PatternBenefit benefit)
      : ConvertToLLVMPattern(rootOpName, context, typeConverter, benefit),
        funcName(funcName) {}

  virtual gpu::Dimension getDimension(Operation *op) const = 0;

  LogicalResult
  matchAndRewrite(Operation *op, ArrayRef<Value> operands,
                  ConversionPatternRewriter &rewriter) const final {
    Operation *moduleOp = op->getParentWithTrait<OpTrait::SymbolTable>();
    assert(moduleOp && "Expecting module");
    Type dimTy = rewriter.getI32Type();
    Type indexTy = getTypeConverter()->getIndexType();
    LLVM::LLVMFuncOp func = lookupOrCreateSPIRVFn(moduleOp, funcName, dimTy,
                                                  indexTy, /*isMemNone=*/true,
                                                  /*isConvergent=*/false);

    Location loc = op->getLoc();
    gpu::Dimension dim = getDimension(op);
    Value dimVal = LLVM::ConstantOp::create(rewriter, loc, dimTy,
                                            static_cast<int64_t>(dim));
    rewriter.replaceOp(op, createSPIRVBuiltinCall(loc, rewriter, func, dimVal));
    return success();
  }

  StringRef funcName;
};

template <typename SourceOp>
struct LaunchConfigOpConversion final : LaunchConfigConversion {
  static StringRef getFuncName();

  explicit LaunchConfigOpConversion(const LLVMTypeConverter &typeConverter,
                                    PatternBenefit benefit = 1)
      : LaunchConfigConversion(getFuncName(), SourceOp::getOperationName(),
                               &typeConverter.getContext(), typeConverter,
                               benefit) {}

  gpu::Dimension getDimension(Operation *op) const final {
    return cast<SourceOp>(op).getDimension();
  }
};

template <>
StringRef LaunchConfigOpConversion<gpu::BlockIdOp>::getFuncName() {
  return "_Z12get_group_idj";
}

template <>
StringRef LaunchConfigOpConversion<gpu::GridDimOp>::getFuncName() {
  return "_Z14get_num_groupsj";
}

template <>
StringRef LaunchConfigOpConversion<gpu::BlockDimOp>::getFuncName() {
  return "_Z14get_local_sizej";
}

template <>
StringRef LaunchConfigOpConversion<gpu::ThreadIdOp>::getFuncName() {
  return "_Z12get_local_idj";
}

template <>
StringRef LaunchConfigOpConversion<gpu::GlobalIdOp>::getFuncName() {
  return "_Z13get_global_idj";
}

//===----------------------------------------------------------------------===//
// Shuffles
//===----------------------------------------------------------------------===//

/// Replace `gpu.shuffle` with an `llvm.call` to the corresponding SPIR-V
/// builtin for `shuffleResult`, keeping `value` and `offset` arguments, and a
/// `true` constant for the `valid` result type. Conversion will only take place
/// if `width` is constant and equal to the `subgroup` pass option:
/// ```
/// // %0 = gpu.shuffle idx %value, %offset, %width : f64
/// %0 = llvm.call spir_funccc @_Z17sub_group_shuffledj(%value, %offset)
///     : (f64, i32) -> f64
/// ```
struct GPUShuffleConversion final : ConvertOpToLLVMPattern<gpu::ShuffleOp> {
  using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern;

  static StringRef getBaseName(gpu::ShuffleMode mode) {
    switch (mode) {
    case gpu::ShuffleMode::IDX:
      return "sub_group_shuffle";
    case gpu::ShuffleMode::XOR:
      return "sub_group_shuffle_xor";
    case gpu::ShuffleMode::UP:
      return "sub_group_shuffle_up";
    case gpu::ShuffleMode::DOWN:
      return "sub_group_shuffle_down";
    }
    llvm_unreachable("Unhandled shuffle mode");
  }

  static std::optional<StringRef> getTypeMangling(Type type) {
    return TypeSwitch<Type, std::optional<StringRef>>(type)
        .Case([](Float16Type) { return "Dhj"; })
        .Case([](Float32Type) { return "fj"; })
        .Case([](Float64Type) { return "dj"; })
        .Case([](IntegerType intTy) -> std::optional<StringRef> {
          switch (intTy.getWidth()) {
          case 8:
            return "cj";
          case 16:
            return "sj";
          case 32:
            return "ij";
          case 64:
            return "lj";
          }
          return std::nullopt;
        })
        .Default(std::nullopt);
  }

  static std::optional<std::string> getFuncName(gpu::ShuffleMode mode,
                                                Type type) {
    StringRef baseName = getBaseName(mode);
    std::optional<StringRef> typeMangling = getTypeMangling(type);
    if (!typeMangling)
      return std::nullopt;
    return llvm::formatv("_Z{}{}{}", baseName.size(), baseName,
                         typeMangling.value());
  }

  /// Get the subgroup size from the target or return a default.
  static std::optional<int> getSubgroupSize(Operation *op) {
    auto parentFunc = op->getParentOfType<LLVM::LLVMFuncOp>();
    if (!parentFunc)
      return std::nullopt;
    return parentFunc.getIntelReqdSubGroupSize();
  }

  static bool hasValidWidth(gpu::ShuffleOp op, int subgroupSize) {
    llvm::APInt val;
    Value width = op.getWidth();
    return matchPattern(width, m_ConstantInt(&val)) && val == subgroupSize;
  }

  static Value bitcastOrExtBeforeShuffle(Value oldVal, Location loc,
                                         ConversionPatternRewriter &rewriter) {
    return TypeSwitch<Type, Value>(oldVal.getType())
        .Case([&](BFloat16Type) {
          return LLVM::BitcastOp::create(rewriter, loc, rewriter.getI16Type(),
                                         oldVal);
        })
        .Case([&](IntegerType intTy) -> Value {
          if (intTy.getWidth() == 1)
            return LLVM::ZExtOp::create(rewriter, loc, rewriter.getI8Type(),
                                        oldVal);
          return oldVal;
        })
        .Default(oldVal);
  }

  static Value bitcastOrTruncAfterShuffle(Value oldVal, Type newTy,
                                          Location loc,
                                          ConversionPatternRewriter &rewriter) {
    return TypeSwitch<Type, Value>(newTy)
        .Case([&](BFloat16Type) {
          return LLVM::BitcastOp::create(rewriter, loc, newTy, oldVal);
        })
        .Case([&](IntegerType intTy) -> Value {
          if (intTy.getWidth() == 1)
            return LLVM::TruncOp::create(rewriter, loc, newTy, oldVal);
          return oldVal;
        })
        .Default(oldVal);
  }

  LogicalResult
  matchAndRewrite(gpu::ShuffleOp op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const final {
    auto maybeSubgroupSize = getSubgroupSize(op);
    if (maybeSubgroupSize && !hasValidWidth(op, maybeSubgroupSize.value()))
      return rewriter.notifyMatchFailure(
          op, "shuffle width and subgroup size mismatch");

    Location loc = op->getLoc();
    Value inValue =
        bitcastOrExtBeforeShuffle(adaptor.getValue(), loc, rewriter);
    std::optional<std::string> funcName =
        getFuncName(op.getMode(), inValue.getType());
    if (!funcName)
      return rewriter.notifyMatchFailure(op, "unsupported value type");

    Operation *moduleOp = op->getParentWithTrait<OpTrait::SymbolTable>();
    assert(moduleOp && "Expecting module");
    Type valueType = inValue.getType();
    Type offsetType = adaptor.getOffset().getType();
    Type resultType = valueType;
    LLVM::LLVMFuncOp func = lookupOrCreateSPIRVFn(
        moduleOp, funcName.value(), {valueType, offsetType}, resultType,
        /*isMemNone=*/false, /*isConvergent=*/true);

    std::array<Value, 2> args{inValue, adaptor.getOffset()};
    Value result =
        createSPIRVBuiltinCall(loc, rewriter, func, args).getResult();
    Value resultOrConversion =
        bitcastOrTruncAfterShuffle(result, op.getType(0), loc, rewriter);

    Value trueVal =
        LLVM::ConstantOp::create(rewriter, loc, rewriter.getI1Type(), true);
    rewriter.replaceOp(op, {resultOrConversion, trueVal});
    return success();
  }
};

class MemorySpaceToOpenCLMemorySpaceConverter final : public TypeConverter {
public:
  MemorySpaceToOpenCLMemorySpaceConverter(MLIRContext *ctx) {
    addConversion([](Type t) { return t; });
    addConversion([ctx](BaseMemRefType memRefType) -> std::optional<Type> {
      // Attach global addr space attribute to memrefs with no addr space attr
      Attribute memSpaceAttr = memRefType.getMemorySpace();
      if (memSpaceAttr)
        return std::nullopt;

      unsigned globalAddrspace = storageClassToAddressSpace(
          spirv::ClientAPI::OpenCL, spirv::StorageClass::CrossWorkgroup);
      Attribute addrSpaceAttr =
          IntegerAttr::get(IntegerType::get(ctx, 64), globalAddrspace);
      if (auto rankedType = dyn_cast<MemRefType>(memRefType)) {
        return MemRefType::get(memRefType.getShape(),
                               memRefType.getElementType(),
                               rankedType.getLayout(), addrSpaceAttr);
      }
      return UnrankedMemRefType::get(memRefType.getElementType(),
                                     addrSpaceAttr);
    });
    addConversion([this](FunctionType type) {
      auto inputs = llvm::map_to_vector(
          type.getInputs(), [this](Type ty) { return convertType(ty); });
      auto results = llvm::map_to_vector(
          type.getResults(), [this](Type ty) { return convertType(ty); });
      return FunctionType::get(type.getContext(), inputs, results);
    });
  }
};

//===----------------------------------------------------------------------===//
// Subgroup query ops.
//===----------------------------------------------------------------------===//

template <typename SubgroupOp>
struct GPUSubgroupOpConversion final : ConvertOpToLLVMPattern<SubgroupOp> {
  using ConvertOpToLLVMPattern<SubgroupOp>::ConvertOpToLLVMPattern;
  using ConvertToLLVMPattern::getTypeConverter;

  LogicalResult
  matchAndRewrite(SubgroupOp op, typename SubgroupOp::Adaptor adaptor,
                  ConversionPatternRewriter &rewriter) const final {
    constexpr StringRef funcName = [] {
      if constexpr (std::is_same_v<SubgroupOp, gpu::SubgroupIdOp>) {
        return "_Z16get_sub_group_id";
      } else if constexpr (std::is_same_v<SubgroupOp, gpu::LaneIdOp>) {
        return "_Z22get_sub_group_local_id";
      } else if constexpr (std::is_same_v<SubgroupOp, gpu::NumSubgroupsOp>) {
        return "_Z18get_num_sub_groups";
      } else if constexpr (std::is_same_v<SubgroupOp, gpu::SubgroupSizeOp>) {
        return "_Z18get_sub_group_size";
      }
    }();

    Operation *moduleOp =
        op->template getParentWithTrait<OpTrait::SymbolTable>();
    Type resultTy = rewriter.getI32Type();
    LLVM::LLVMFuncOp func =
        lookupOrCreateSPIRVFn(moduleOp, funcName, {}, resultTy,
                              /*isMemNone=*/false, /*isConvergent=*/false);

    Location loc = op->getLoc();
    Value result = createSPIRVBuiltinCall(loc, rewriter, func, {}).getResult();

    Type indexTy = getTypeConverter()->getIndexType();
    if (resultTy != indexTy) {
      if (indexTy.getIntOrFloatBitWidth() < resultTy.getIntOrFloatBitWidth()) {
        return failure();
      }
      result = LLVM::ZExtOp::create(rewriter, loc, indexTy, result);
    }

    rewriter.replaceOp(op, result);
    return success();
  }
};

//===----------------------------------------------------------------------===//
// GPU To LLVM-SPV Pass.
//===----------------------------------------------------------------------===//

struct GPUToLLVMSPVConversionPass final
    : impl::ConvertGpuOpsToLLVMSPVOpsBase<GPUToLLVMSPVConversionPass> {
  using Base::Base;

  void runOnOperation() final {
    MLIRContext *context = &getContext();
    RewritePatternSet patterns(context);

    LowerToLLVMOptions options(context);
    options.overrideIndexBitwidth(this->use64bitIndex ? 64 : 32);
    LLVMTypeConverter converter(context, options);
    LLVMConversionTarget target(*context);

    // Force OpenCL address spaces when they are not present
    {
      MemorySpaceToOpenCLMemorySpaceConverter converter(context);
      AttrTypeReplacer replacer;
      replacer.addReplacement([&converter](BaseMemRefType origType)
                                  -> std::optional<BaseMemRefType> {
        return converter.convertType<BaseMemRefType>(origType);
      });

      replacer.recursivelyReplaceElementsIn(getOperation(),
                                            /*replaceAttrs=*/true,
                                            /*replaceLocs=*/false,
                                            /*replaceTypes=*/true);
    }

    target.addIllegalOp<gpu::BarrierOp, gpu::BlockDimOp, gpu::BlockIdOp,
                        gpu::GPUFuncOp, gpu::GlobalIdOp, gpu::GridDimOp,
                        gpu::LaneIdOp, gpu::NumSubgroupsOp, gpu::ReturnOp,
                        gpu::ShuffleOp, gpu::SubgroupIdOp, gpu::SubgroupSizeOp,
                        gpu::ThreadIdOp, gpu::PrintfOp>();

    populateGpuToLLVMSPVConversionPatterns(converter, patterns);
    populateGpuMemorySpaceAttributeConversions(converter);
    patterns.add<GPUPrintfOpToLLVMCallLowering>(converter, /*addressSpace=*/2,
                                                LLVM::cconv::CConv::SPIR_FUNC,
                                                "_Z6printfPU3AS2Kcz");

    if (failed(applyPartialConversion(getOperation(), target,
                                      std::move(patterns))))
      signalPassFailure();
  }
};
} // namespace

//===----------------------------------------------------------------------===//
// GPU To LLVM-SPV Patterns.
//===----------------------------------------------------------------------===//

namespace mlir {
namespace {
static unsigned
gpuAddressSpaceToOCLAddressSpace(gpu::AddressSpace addressSpace) {
  constexpr spirv::ClientAPI clientAPI = spirv::ClientAPI::OpenCL;
  return storageClassToAddressSpace(clientAPI,
                                    addressSpaceToStorageClass(addressSpace));
}
} // namespace

void populateGpuToLLVMSPVConversionPatterns(
    const LLVMTypeConverter &typeConverter, RewritePatternSet &patterns) {
  patterns.add<GPUBarrierConversion, GPUReturnOpLowering, GPUShuffleConversion,
               GPUSubgroupOpConversion<gpu::LaneIdOp>,
               GPUSubgroupOpConversion<gpu::NumSubgroupsOp>,
               GPUSubgroupOpConversion<gpu::SubgroupIdOp>,
               GPUSubgroupOpConversion<gpu::SubgroupSizeOp>,
               LaunchConfigOpConversion<gpu::BlockDimOp>,
               LaunchConfigOpConversion<gpu::BlockIdOp>,
               LaunchConfigOpConversion<gpu::GlobalIdOp>,
               LaunchConfigOpConversion<gpu::GridDimOp>,
               LaunchConfigOpConversion<gpu::ThreadIdOp>>(typeConverter);
  MLIRContext *context = &typeConverter.getContext();
  unsigned privateAddressSpace =
      gpuAddressSpaceToOCLAddressSpace(gpu::AddressSpace::Private);
  unsigned localAddressSpace =
      gpuAddressSpaceToOCLAddressSpace(gpu::AddressSpace::Workgroup);
  OperationName llvmFuncOpName(LLVM::LLVMFuncOp::getOperationName(), context);
  StringAttr kernelBlockSizeAttributeName =
      LLVM::LLVMFuncOp::getReqdWorkGroupSizeAttrName(llvmFuncOpName);
  patterns.add<GPUFuncOpLowering>(
      typeConverter,
      GPUFuncOpLoweringOptions{
          privateAddressSpace, localAddressSpace,
          /*kernelAttributeName=*/{}, kernelBlockSizeAttributeName,
          /*kernelClusterSizeAttributeName=*/{}, LLVM::CConv::SPIR_KERNEL,
          LLVM::CConv::SPIR_FUNC,
          /*encodeWorkgroupAttributionsAsArguments=*/true});
}

void populateGpuMemorySpaceAttributeConversions(TypeConverter &typeConverter) {
  populateGpuMemorySpaceAttributeConversions(typeConverter,
                                             gpuAddressSpaceToOCLAddressSpace);
}
} // namespace mlir
