Files
clang-p2996/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVMPass.cpp
Victor Perez 12ce9fd124 [mlir][spirv] Add client-api option to -convert-spirv-to-llvm
Option to express that `spirv` StorageClasses should be mapped to LLVM
address spaces in the conversion process. This mapping will be
client-dependent.

The client API cannot be taken from the code as more than one module
could be present, resulting in more than one VCE triple and different
StorageClass to address space mappings. This information would not be
available during type conversion.

A specific mapping for the OpenCL client is defined, based on [the
OpenCL Extended Instruction
Set](https://registry.khronos.org/SPIR-V/specs/unified1/OpenCL.ExtendedInstructionSet.100.html#_binary_form)
and [this
mapping](3edd338a64/clang/lib/Basic/Targets/SPIR.h (L27)).

Signed-off-by: Victor Perez <victor.perez@codeplay.com>

Reviewed By: antiagainst, kuhar

Differential Revision: https://reviews.llvm.org/D158627
2023-08-24 09:48:36 +01:00

75 lines
2.5 KiB
C++

//===- SPIRVToLLVMPass.cpp - SPIR-V to LLVM Passes ------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file implements a pass to convert MLIR SPIR-V ops into LLVM ops
//
//===----------------------------------------------------------------------===//
#include "mlir/Conversion/SPIRVToLLVM/SPIRVToLLVMPass.h"
#include "mlir/Conversion/LLVMCommon/TypeConverter.h"
#include "mlir/Conversion/SPIRVToLLVM/SPIRVToLLVM.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Dialect/SPIRV/IR/SPIRVDialect.h"
#include "mlir/Dialect/SPIRV/IR/SPIRVEnums.h"
#include "mlir/Pass/Pass.h"
namespace mlir {
#define GEN_PASS_DEF_CONVERTSPIRVTOLLVMPASS
#include "mlir/Conversion/Passes.h.inc"
} // namespace mlir
using namespace mlir;
namespace {
/// A pass converting MLIR SPIR-V operations into LLVM dialect.
class ConvertSPIRVToLLVMPass
: public impl::ConvertSPIRVToLLVMPassBase<ConvertSPIRVToLLVMPass> {
void runOnOperation() override;
public:
using Base::Base;
};
} // namespace
void ConvertSPIRVToLLVMPass::runOnOperation() {
MLIRContext *context = &getContext();
ModuleOp module = getOperation();
LowerToLLVMOptions options(&getContext());
options.useOpaquePointers = useOpaquePointers;
LLVMTypeConverter converter(&getContext(), options);
// Encode global variable's descriptor set and binding if they exist.
encodeBindAttribute(module);
RewritePatternSet patterns(context);
populateSPIRVToLLVMTypeConversion(converter, clientAPI);
populateSPIRVToLLVMModuleConversionPatterns(converter, patterns);
populateSPIRVToLLVMConversionPatterns(converter, patterns, clientAPI);
populateSPIRVToLLVMFunctionConversionPatterns(converter, patterns);
ConversionTarget target(*context);
target.addIllegalDialect<spirv::SPIRVDialect>();
target.addLegalDialect<LLVM::LLVMDialect>();
if (clientAPI != spirv::ClientAPI::OpenCL &&
clientAPI != spirv::ClientAPI::Unknown)
getOperation()->emitWarning()
<< "address space mapping for client '"
<< spirv::stringifyClientAPI(clientAPI) << "' not implemented";
// Set `ModuleOp` as legal for `spirv.module` conversion.
target.addLegalOp<ModuleOp>();
if (failed(applyPartialConversion(module, target, std::move(patterns))))
signalPassFailure();
}