1 //===- ModuleTranslation.h - MLIR to LLVM conversion ------------*- C++ -*-===//
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 the translation between an MLIR LLVM dialect module and
10 // the corresponding LLVMIR module. It only handles core LLVM IR operations.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_TARGET_LLVMIR_MODULETRANSLATION_H
15 #define MLIR_TARGET_LLVMIR_MODULETRANSLATION_H
16 
17 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
18 #include "mlir/Dialect/LLVMIR/Transforms/LegalizeForExport.h"
19 #include "mlir/IR/Block.h"
20 #include "mlir/IR/BuiltinOps.h"
21 #include "mlir/IR/Value.h"
22 #include "mlir/Target/LLVMIR/TypeTranslation.h"
23 
24 #include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
25 #include "llvm/IR/BasicBlock.h"
26 #include "llvm/IR/Function.h"
27 #include "llvm/IR/IRBuilder.h"
28 #include "llvm/IR/MatrixBuilder.h"
29 #include "llvm/IR/Value.h"
30 
31 namespace mlir {
32 class Attribute;
33 class Location;
34 class ModuleOp;
35 class Operation;
36 
37 namespace LLVM {
38 
39 namespace detail {
40 class DebugTranslation;
41 } // end namespace detail
42 
43 class LLVMFuncOp;
44 
45 /// Implementation class for module translation. Holds a reference to the module
46 /// being translated, and the mappings between the original and the translated
47 /// functions, basic blocks and values. It is practically easier to hold these
48 /// mappings in one class since the conversion of control flow operations
49 /// needs to look up block and function mappings.
50 class ModuleTranslation {
51 public:
52   template <typename T = ModuleTranslation>
53   static std::unique_ptr<llvm::Module>
54   translateModule(Operation *m, llvm::LLVMContext &llvmContext,
55                   StringRef name = "LLVMDialectModule") {
56     if (!satisfiesLLVMModule(m))
57       return nullptr;
58     if (failed(checkSupportedModuleOps(m)))
59       return nullptr;
60     std::unique_ptr<llvm::Module> llvmModule =
61         prepareLLVMModule(m, llvmContext, name);
62 
63     LLVM::ensureDistinctSuccessors(m);
64 
65     T translator(m, std::move(llvmModule));
66     if (failed(translator.convertFunctionSignatures()))
67       return nullptr;
68     if (failed(translator.convertGlobals()))
69       return nullptr;
70     if (failed(translator.convertFunctions()))
71       return nullptr;
72 
73     return std::move(translator.llvmModule);
74   }
75 
76   /// A helper method to get the single Block in an operation honoring LLVM's
77   /// module requirements.
getModuleBody(Operation * m)78   static Block &getModuleBody(Operation *m) { return m->getRegion(0).front(); }
79 
80 protected:
81   /// Translate the given MLIR module expressed in MLIR LLVM IR dialect into an
82   /// LLVM IR module. The MLIR LLVM IR dialect holds a pointer to an
83   /// LLVMContext, the LLVM IR module will be created in that context.
84   ModuleTranslation(Operation *module,
85                     std::unique_ptr<llvm::Module> llvmModule);
86   virtual ~ModuleTranslation();
87 
88   virtual LogicalResult convertOperation(Operation &op,
89                                          llvm::IRBuilder<> &builder);
90   virtual LogicalResult convertOmpOperation(Operation &op,
91                                             llvm::IRBuilder<> &builder);
92   virtual LogicalResult convertOmpParallel(Operation &op,
93                                            llvm::IRBuilder<> &builder);
94   virtual LogicalResult convertOmpMaster(Operation &op,
95                                          llvm::IRBuilder<> &builder);
96   void convertOmpOpRegions(Region &region,
97                            DenseMap<Value, llvm::Value *> &valueMapping,
98                            DenseMap<Block *, llvm::BasicBlock *> &blockMapping,
99                            llvm::Instruction *codeGenIPBBTI,
100                            llvm::BasicBlock &continuationIP,
101                            llvm::IRBuilder<> &builder,
102                            LogicalResult &bodyGenStatus);
103   /// Converts the type from MLIR LLVM dialect to LLVM.
104   llvm::Type *convertType(LLVMType type);
105 
106   static std::unique_ptr<llvm::Module>
107   prepareLLVMModule(Operation *m, llvm::LLVMContext &llvmContext,
108                     StringRef name);
109 
110   /// A helper to look up remapped operands in the value remapping table.
111   SmallVector<llvm::Value *, 8> lookupValues(ValueRange values);
112 
113 private:
114   /// Check whether the module contains only supported ops directly in its body.
115   static LogicalResult checkSupportedModuleOps(Operation *m);
116 
117   LogicalResult convertFunctionSignatures();
118   LogicalResult convertFunctions();
119   LogicalResult convertGlobals();
120   LogicalResult convertOneFunction(LLVMFuncOp func);
121   LogicalResult convertBlock(Block &bb, bool ignoreArguments);
122 
123   llvm::Constant *getLLVMConstant(llvm::Type *llvmType, Attribute attr,
124                                   Location loc);
125 
126   /// Original and translated module.
127   Operation *mlirModule;
128   std::unique_ptr<llvm::Module> llvmModule;
129   /// A converter for translating debug information.
130   std::unique_ptr<detail::DebugTranslation> debugTranslation;
131 
132   /// Builder for LLVM IR generation of OpenMP constructs.
133   std::unique_ptr<llvm::OpenMPIRBuilder> ompBuilder;
134   /// Precomputed pointer to OpenMP dialect. Note this can be nullptr if the
135   /// OpenMP dialect hasn't been loaded (it is always loaded if there are OpenMP
136   /// operations in the module though).
137   const Dialect *ompDialect;
138   /// Stack which stores the target block to which a branch a must be added when
139   /// a terminator is seen. A stack is required to handle nested OpenMP parallel
140   /// regions.
141   SmallVector<llvm::BasicBlock *, 4> ompContinuationIPStack;
142 
143   /// Mappings between llvm.mlir.global definitions and corresponding globals.
144   DenseMap<Operation *, llvm::GlobalValue *> globalsMapping;
145 
146   /// A stateful object used to translate types.
147   TypeToLLVMIRTranslator typeTranslator;
148 
149 protected:
150   /// Mappings between original and translated values, used for lookups.
151   llvm::StringMap<llvm::Function *> functionMapping;
152   DenseMap<Value, llvm::Value *> valueMapping;
153   DenseMap<Block *, llvm::BasicBlock *> blockMapping;
154 };
155 
156 } // namespace LLVM
157 } // namespace mlir
158 
159 #endif // MLIR_TARGET_LLVMIR_MODULETRANSLATION_H
160