1 //===- ConvertToLLVMIR.cpp - MLIR to LLVM IR 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 between the MLIR LLVM dialect and LLVM IR.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "mlir/Target/LLVMIR.h"
14 
15 #include "mlir/Dialect/LLVMIR/LLVMAVX512Dialect.h"
16 #include "mlir/Dialect/LLVMIR/LLVMArmNeonDialect.h"
17 #include "mlir/Dialect/LLVMIR/LLVMArmSVEDialect.h"
18 #include "mlir/Dialect/LLVMIR/NVVMDialect.h"
19 #include "mlir/Dialect/LLVMIR/ROCDLDialect.h"
20 #include "mlir/Dialect/OpenMP/OpenMPDialect.h"
21 #include "mlir/Target/LLVMIR/Dialect/LLVMAVX512/LLVMAVX512ToLLVMIRTranslation.h"
22 #include "mlir/Target/LLVMIR/Dialect/LLVMArmNeon/LLVMArmNeonToLLVMIRTranslation.h"
23 #include "mlir/Target/LLVMIR/Dialect/LLVMArmSVE/LLVMArmSVEToLLVMIRTranslation.h"
24 #include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h"
25 #include "mlir/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.h"
26 #include "mlir/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h"
27 #include "mlir/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.h"
28 #include "mlir/Target/LLVMIR/ModuleTranslation.h"
29 #include "mlir/Translation.h"
30 
31 #include "llvm/ADT/StringRef.h"
32 #include "llvm/IR/Module.h"
33 #include "llvm/IR/Verifier.h"
34 #include "llvm/Support/ToolOutputFile.h"
35 
36 using namespace mlir;
37 
38 std::unique_ptr<llvm::Module>
39 mlir::translateModuleToLLVMIR(Operation *op, llvm::LLVMContext &llvmContext,
40                               StringRef name) {
41   auto llvmModule =
42       LLVM::ModuleTranslation::translateModule<>(op, llvmContext, name);
43   if (!llvmModule)
44     emitError(op->getLoc(), "Fail to convert MLIR to LLVM IR");
45   else if (verifyModule(*llvmModule))
46     emitError(op->getLoc(), "LLVM IR fails to verify");
47   return llvmModule;
48 }
49 
50 void mlir::registerLLVMDialectTranslation(DialectRegistry &registry) {
51   registry.insert<LLVM::LLVMDialect>();
52   registry.addDialectInterface<LLVM::LLVMDialect,
53                                LLVMDialectLLVMIRTranslationInterface>();
54 }
55 
56 void mlir::registerLLVMDialectTranslation(MLIRContext &context) {
57   auto *dialect = context.getLoadedDialect<LLVM::LLVMDialect>();
58   if (!dialect || dialect->getRegisteredInterface<
59                       LLVMDialectLLVMIRTranslationInterface>() == nullptr) {
60     DialectRegistry registry;
61     registry.insert<LLVM::LLVMDialect>();
62     registry.addDialectInterface<LLVM::LLVMDialect,
63                                  LLVMDialectLLVMIRTranslationInterface>();
64     context.appendDialectRegistry(registry);
65   }
66 }
67 
68 namespace mlir {
69 void registerToLLVMIRTranslation() {
70   TranslateFromMLIRRegistration registration(
71       "mlir-to-llvmir",
72       [](ModuleOp module, raw_ostream &output) {
73         llvm::LLVMContext llvmContext;
74         auto llvmModule = LLVM::ModuleTranslation::translateModule<>(
75             module, llvmContext, "LLVMDialectModule");
76         if (!llvmModule)
77           return failure();
78 
79         llvmModule->print(output, nullptr);
80         return success();
81       },
82       [](DialectRegistry &registry) {
83         registry.insert<omp::OpenMPDialect, LLVM::LLVMAVX512Dialect,
84                         LLVM::LLVMArmSVEDialect, LLVM::LLVMArmNeonDialect,
85                         NVVM::NVVMDialect, ROCDL::ROCDLDialect>();
86         registry.addDialectInterface<omp::OpenMPDialect,
87                                      OpenMPDialectLLVMIRTranslationInterface>();
88         registry
89             .addDialectInterface<LLVM::LLVMAVX512Dialect,
90                                  LLVMAVX512DialectLLVMIRTranslationInterface>();
91         registry.addDialectInterface<
92             LLVM::LLVMArmNeonDialect,
93             LLVMArmNeonDialectLLVMIRTranslationInterface>();
94         registry
95             .addDialectInterface<LLVM::LLVMArmSVEDialect,
96                                  LLVMArmSVEDialectLLVMIRTranslationInterface>();
97         registry.addDialectInterface<NVVM::NVVMDialect,
98                                      NVVMDialectLLVMIRTranslationInterface>();
99         registry.addDialectInterface<ROCDL::ROCDLDialect,
100                                      ROCDLDialectLLVMIRTranslationInterface>();
101         registerLLVMDialectTranslation(registry);
102       });
103 }
104 } // namespace mlir
105