1 //===- LLVMIRToNVVMTranslation.cpp - Translate LLVM IR to NVVM dialect ----===// 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 between LLVM IR and the MLIR NVVM dialect. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "mlir/Target/LLVMIR/Dialect/NVVM/LLVMIRToNVVMTranslation.h" 14 #include "mlir/Dialect/LLVMIR/NVVMDialect.h" 15 #include "mlir/Target/LLVMIR/ModuleImport.h" 16 17 #include "llvm/IR/ConstantRange.h" 18 #include "llvm/IR/IntrinsicsNVPTX.h" 19 20 using namespace mlir; 21 using namespace mlir::NVVM; 22 23 /// Returns true if the LLVM IR intrinsic is convertible to an MLIR NVVM dialect 24 /// intrinsic. Returns false otherwise. 25 static bool isConvertibleIntrinsic(llvm::Intrinsic::ID id) { 26 static const DenseSet<unsigned> convertibleIntrinsics = { 27 #include "mlir/Dialect/LLVMIR/NVVMConvertibleLLVMIRIntrinsics.inc" 28 }; 29 return convertibleIntrinsics.contains(id); 30 } 31 32 /// Returns the list of LLVM IR intrinsic identifiers that are convertible to 33 /// MLIR NVVM dialect intrinsics. 34 static ArrayRef<unsigned> getSupportedIntrinsicsImpl() { 35 static const SmallVector<unsigned> convertibleIntrinsics = { 36 #include "mlir/Dialect/LLVMIR/NVVMConvertibleLLVMIRIntrinsics.inc" 37 }; 38 return convertibleIntrinsics; 39 } 40 41 /// Converts the LLVM intrinsic to an MLIR NVVM dialect operation if a 42 /// conversion exits. Returns failure otherwise. 43 static LogicalResult convertIntrinsicImpl(OpBuilder &odsBuilder, 44 llvm::CallInst *inst, 45 LLVM::ModuleImport &moduleImport) { 46 llvm::Intrinsic::ID intrinsicID = inst->getIntrinsicID(); 47 48 // Check if the intrinsic is convertible to an MLIR dialect counterpart and 49 // copy the arguments to an an LLVM operands array reference for conversion. 50 if (isConvertibleIntrinsic(intrinsicID)) { 51 SmallVector<llvm::Value *> args(inst->args()); 52 ArrayRef<llvm::Value *> llvmOperands(args); 53 54 SmallVector<llvm::OperandBundleUse> llvmOpBundles; 55 llvmOpBundles.reserve(inst->getNumOperandBundles()); 56 for (unsigned i = 0; i < inst->getNumOperandBundles(); ++i) 57 llvmOpBundles.push_back(inst->getOperandBundleAt(i)); 58 59 #include "mlir/Dialect/LLVMIR/NVVMFromLLVMIRConversions.inc" 60 } 61 62 return failure(); 63 } 64 65 namespace { 66 67 /// Implementation of the dialect interface that converts operations belonging 68 /// to the NVVM dialect. 69 class NVVMDialectLLVMIRImportInterface : public LLVMImportDialectInterface { 70 public: 71 using LLVMImportDialectInterface::LLVMImportDialectInterface; 72 73 /// Converts the LLVM intrinsic to an MLIR NVVM dialect operation if a 74 /// conversion exits. Returns failure otherwise. 75 LogicalResult convertIntrinsic(OpBuilder &builder, llvm::CallInst *inst, 76 LLVM::ModuleImport &moduleImport) const final { 77 return convertIntrinsicImpl(builder, inst, moduleImport); 78 } 79 80 /// Returns the list of LLVM IR intrinsic identifiers that are convertible to 81 /// MLIR NVVM dialect intrinsics. 82 ArrayRef<unsigned> getSupportedIntrinsics() const final { 83 return getSupportedIntrinsicsImpl(); 84 } 85 }; 86 87 } // namespace 88 89 void mlir::registerNVVMDialectImport(DialectRegistry ®istry) { 90 registry.insert<NVVM::NVVMDialect>(); 91 registry.addExtension(+[](MLIRContext *ctx, NVVM::NVVMDialect *dialect) { 92 dialect->addInterfaces<NVVMDialectLLVMIRImportInterface>(); 93 }); 94 } 95 96 void mlir::registerNVVMDialectImport(MLIRContext &context) { 97 DialectRegistry registry; 98 registerNVVMDialectImport(registry); 99 context.appendDialectRegistry(registry); 100 } 101