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                   });