github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/third_party/mlir/lib/Target/LLVMIR/ConvertToNVVMIR.cpp (about) 1 //===- ConvertToNVVMIR.cpp - MLIR to LLVM IR conversion -------------------===// 2 // 3 // Copyright 2019 The MLIR Authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 // ============================================================================= 17 // 18 // This file implements a translation between the MLIR LLVM + NVVM dialects and 19 // LLVM IR with NVVM intrinsics and metadata. 20 // 21 //===----------------------------------------------------------------------===// 22 23 #include "mlir/Target/NVVMIR.h" 24 25 #include "mlir/Dialect/GPU/GPUDialect.h" 26 #include "mlir/Dialect/LLVMIR/NVVMDialect.h" 27 #include "mlir/IR/Function.h" 28 #include "mlir/IR/Module.h" 29 #include "mlir/Support/FileUtilities.h" 30 #include "mlir/Target/LLVMIR/ModuleTranslation.h" 31 #include "mlir/Translation.h" 32 33 #include "llvm/ADT/StringRef.h" 34 #include "llvm/IR/Module.h" 35 #include "llvm/Support/ToolOutputFile.h" 36 37 using namespace mlir; 38 39 namespace { 40 static llvm::Value *createIntrinsicCall(llvm::IRBuilder<> &builder, 41 llvm::Intrinsic::ID intrinsic, 42 ArrayRef<llvm::Value *> args = {}) { 43 llvm::Module *module = builder.GetInsertBlock()->getModule(); 44 llvm::Function *fn = llvm::Intrinsic::getDeclaration(module, intrinsic); 45 return builder.CreateCall(fn, args); 46 } 47 48 class ModuleTranslation : public LLVM::ModuleTranslation { 49 50 public: 51 explicit ModuleTranslation(ModuleOp module) 52 : LLVM::ModuleTranslation(module) {} 53 ~ModuleTranslation() override {} 54 55 protected: 56 LogicalResult convertOperation(Operation &opInst, 57 llvm::IRBuilder<> &builder) override { 58 59 #include "mlir/Dialect/LLVMIR/NVVMConversions.inc" 60 61 return LLVM::ModuleTranslation::convertOperation(opInst, builder); 62 } 63 }; 64 } // namespace 65 66 std::unique_ptr<llvm::Module> mlir::translateModuleToNVVMIR(ModuleOp m) { 67 ModuleTranslation translation(m); 68 auto llvmModule = 69 LLVM::ModuleTranslation::translateModule<ModuleTranslation>(m); 70 71 // Insert the nvvm.annotations kernel so that the NVVM backend recognizes the 72 // function as a kernel. 73 for (FuncOp func : m.getOps<FuncOp>()) { 74 if (!func.getAttrOfType<UnitAttr>(gpu::GPUDialect::getKernelFuncAttrName())) 75 continue; 76 77 auto *llvmFunc = llvmModule->getFunction(func.getName()); 78 79 llvm::Metadata *llvmMetadata[] = { 80 llvm::ValueAsMetadata::get(llvmFunc), 81 llvm::MDString::get(llvmModule->getContext(), "kernel"), 82 llvm::ValueAsMetadata::get(llvm::ConstantInt::get( 83 llvm::Type::getInt32Ty(llvmModule->getContext()), 1))}; 84 llvm::MDNode *llvmMetadataNode = 85 llvm::MDNode::get(llvmModule->getContext(), llvmMetadata); 86 llvmModule->getOrInsertNamedMetadata("nvvm.annotations") 87 ->addOperand(llvmMetadataNode); 88 } 89 90 return llvmModule; 91 } 92 93 static TranslateFromMLIRRegistration 94 registration("mlir-to-nvvmir", 95 [](ModuleOp module, llvm::StringRef outputFilename) { 96 if (!module) 97 return failure(); 98 99 auto llvmModule = mlir::translateModuleToNVVMIR(module); 100 if (!llvmModule) 101 return failure(); 102 103 auto file = openOutputFile(outputFilename); 104 if (!file) 105 return failure(); 106 107 llvmModule->print(file->os(), nullptr); 108 file->keep(); 109 return success(); 110 });