Files
clang-p2996/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVMPass.cpp
Markus Böck 19b1e27fcd [mlir][SPIRVToLLVM] Add pass option to emit opaque-pointers
Part of https://discourse.llvm.org/t/rfc-switching-the-llvm-dialect-and-dialect-lowerings-to-opaque-pointers/68179

This patch adds the pass option and required changes to the patterns to support the emission of LLVM IR opaque pointers. Given how close SPIRV semantics are to LLVM IR semantics this boils down to just a few changes:
* Making sure that GEP and alloca are built with the explicit base pointer type
* creating opaque pointers instead of typed pointers if requested
* omitting pointer to pointer bitcasts

Differential Revision: https://reviews.llvm.org/D143900
2023-02-13 22:24:20 +01:00

68 lines
2.2 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/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);
populateSPIRVToLLVMModuleConversionPatterns(converter, patterns);
populateSPIRVToLLVMConversionPatterns(converter, patterns);
populateSPIRVToLLVMFunctionConversionPatterns(converter, patterns);
ConversionTarget target(*context);
target.addIllegalDialect<spirv::SPIRVDialect>();
target.addLegalDialect<LLVM::LLVMDialect>();
// Set `ModuleOp` as legal for `spirv.module` conversion.
target.addLegalOp<ModuleOp>();
if (failed(applyPartialConversion(module, target, std::move(patterns))))
signalPassFailure();
}