1 | //===- SPIRVToLLVMPass.cpp - SPIR-V to LLVM Passes ------------------------===// |
---|---|
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file implements a pass to convert MLIR SPIR-V ops into LLVM ops |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "mlir/Conversion/SPIRVToLLVM/SPIRVToLLVMPass.h" |
14 | |
15 | #include "mlir/Conversion/LLVMCommon/TypeConverter.h" |
16 | #include "mlir/Conversion/SPIRVToLLVM/SPIRVToLLVM.h" |
17 | #include "mlir/Dialect/LLVMIR/LLVMDialect.h" |
18 | #include "mlir/Dialect/SPIRV/IR/SPIRVDialect.h" |
19 | #include "mlir/Dialect/SPIRV/IR/SPIRVEnums.h" |
20 | #include "mlir/Pass/Pass.h" |
21 | |
22 | namespace mlir { |
23 | #define GEN_PASS_DEF_CONVERTSPIRVTOLLVMPASS |
24 | #include "mlir/Conversion/Passes.h.inc" |
25 | } // namespace mlir |
26 | |
27 | using namespace mlir; |
28 | |
29 | namespace { |
30 | /// A pass converting MLIR SPIR-V operations into LLVM dialect. |
31 | class ConvertSPIRVToLLVMPass |
32 | : public impl::ConvertSPIRVToLLVMPassBase<ConvertSPIRVToLLVMPass> { |
33 | void runOnOperation() override; |
34 | |
35 | public: |
36 | using Base::Base; |
37 | }; |
38 | } // namespace |
39 | |
40 | void ConvertSPIRVToLLVMPass::runOnOperation() { |
41 | MLIRContext *context = &getContext(); |
42 | ModuleOp module = getOperation(); |
43 | |
44 | LowerToLLVMOptions options(&getContext()); |
45 | |
46 | LLVMTypeConverter converter(&getContext(), options); |
47 | |
48 | // Encode global variable's descriptor set and binding if they exist. |
49 | encodeBindAttribute(module); |
50 | |
51 | RewritePatternSet patterns(context); |
52 | |
53 | populateSPIRVToLLVMTypeConversion(converter, clientAPI); |
54 | |
55 | populateSPIRVToLLVMModuleConversionPatterns(typeConverter&: converter, patterns); |
56 | populateSPIRVToLLVMConversionPatterns(converter, patterns, clientAPI); |
57 | populateSPIRVToLLVMFunctionConversionPatterns(typeConverter&: converter, patterns); |
58 | |
59 | ConversionTarget target(*context); |
60 | target.addIllegalDialect<spirv::SPIRVDialect>(); |
61 | target.addLegalDialect<LLVM::LLVMDialect>(); |
62 | |
63 | if (clientAPI != spirv::ClientAPI::OpenCL && |
64 | clientAPI != spirv::ClientAPI::Unknown) |
65 | getOperation()->emitWarning() |
66 | << "address space mapping for client '" |
67 | << spirv::stringifyClientAPI(clientAPI) << "' not implemented"; |
68 | |
69 | // Set `ModuleOp` as legal for `spirv.module` conversion. |
70 | target.addLegalOp<ModuleOp>(); |
71 | if (failed(applyPartialConversion(module, target, std::move(patterns)))) |
72 | signalPassFailure(); |
73 | } |
74 |