1//===- NVVMToLLVM.cpp - NVVM to LLVM dialect conversion -----------------===//
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 translation NVVM ops which is not supported in LLVM
10// core.
11//
12//===----------------------------------------------------------------------===//
13
14#include "mlir/Conversion/NVVMToLLVM/NVVMToLLVM.h"
15
16#include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
17#include "mlir/Conversion/LLVMCommon/Pattern.h"
18#include "mlir/Dialect/Func/IR/FuncOps.h"
19#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
20#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
21#include "mlir/Dialect/LLVMIR/NVVMDialect.h"
22#include "mlir/IR/MLIRContext.h"
23#include "mlir/IR/PatternMatch.h"
24#include "mlir/IR/TypeUtilities.h"
25#include "mlir/IR/Value.h"
26#include "mlir/Pass/Pass.h"
27#include "mlir/Support/LLVM.h"
28#include "mlir/Support/LogicalResult.h"
29#include "llvm/Support/raw_ostream.h"
30
31#define DEBUG_TYPE "nvvm-to-llvm"
32#define DBGS() (llvm::dbgs() << "[" DEBUG_TYPE "]: ")
33#define DBGSNL() (llvm::dbgs() << "\n")
34
35namespace mlir {
36#define GEN_PASS_DEF_CONVERTNVVMTOLLVMPASS
37#include "mlir/Conversion/Passes.h.inc"
38} // namespace mlir
39
40using namespace mlir;
41using namespace NVVM;
42
43namespace {
44
45struct PtxLowering
46 : public OpInterfaceRewritePattern<BasicPtxBuilderInterface> {
47 using OpInterfaceRewritePattern<
48 BasicPtxBuilderInterface>::OpInterfaceRewritePattern;
49
50 PtxLowering(MLIRContext *context, PatternBenefit benefit = 2)
51 : OpInterfaceRewritePattern(context, benefit) {}
52
53 LogicalResult matchAndRewrite(BasicPtxBuilderInterface op,
54 PatternRewriter &rewriter) const override {
55 if (op.hasIntrinsic()) {
56 LLVM_DEBUG(DBGS() << "Ptx Builder does not lower \n\t" << op << "\n");
57 return failure();
58 }
59
60 SmallVector<std::pair<Value, PTXRegisterMod>> asmValues;
61 LLVM_DEBUG(DBGS() << op.getPtx() << "\n");
62 PtxBuilder generator(op, rewriter);
63
64 op.getAsmValues(rewriter, asmValues);
65 for (auto &[asmValue, modifier] : asmValues) {
66 LLVM_DEBUG(DBGSNL() << asmValue << "\t Modifier : " << &modifier);
67 generator.insertValue(asmValue, modifier);
68 }
69
70 generator.buildAndReplaceOp();
71 return success();
72 }
73};
74
75struct ConvertNVVMToLLVMPass
76 : public impl::ConvertNVVMToLLVMPassBase<ConvertNVVMToLLVMPass> {
77 using Base::Base;
78
79 void getDependentDialects(DialectRegistry &registry) const override {
80 registry.insert<LLVM::LLVMDialect, NVVM::NVVMDialect>();
81 }
82
83 void runOnOperation() override {
84 ConversionTarget target(getContext());
85 target.addLegalDialect<::mlir::LLVM::LLVMDialect>();
86 RewritePatternSet pattern(&getContext());
87 mlir::populateNVVMToLLVMConversionPatterns(patterns&: pattern);
88 if (failed(
89 applyPartialConversion(getOperation(), target, std::move(pattern))))
90 signalPassFailure();
91 }
92};
93
94/// Implement the interface to convert NVVM to LLVM.
95struct NVVMToLLVMDialectInterface : public ConvertToLLVMPatternInterface {
96 using ConvertToLLVMPatternInterface::ConvertToLLVMPatternInterface;
97 void loadDependentDialects(MLIRContext *context) const final {
98 context->loadDialect<NVVMDialect>();
99 }
100
101 /// Hook for derived dialect interface to provide conversion patterns
102 /// and mark dialect legal for the conversion target.
103 void populateConvertToLLVMConversionPatterns(
104 ConversionTarget &target, LLVMTypeConverter &typeConverter,
105 RewritePatternSet &patterns) const final {
106 populateNVVMToLLVMConversionPatterns(patterns);
107 }
108};
109
110} // namespace
111
112void mlir::populateNVVMToLLVMConversionPatterns(RewritePatternSet &patterns) {
113 patterns.add<PtxLowering>(arg: patterns.getContext());
114}
115
116void mlir::registerConvertNVVMToLLVMInterface(DialectRegistry &registry) {
117 registry.addExtension(extensionFn: +[](MLIRContext *ctx, NVVMDialect *dialect) {
118 dialect->addInterfaces<NVVMToLLVMDialectInterface>();
119 });
120}
121

source code of mlir/lib/Conversion/NVVMToLLVM/NVVMToLLVM.cpp