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 ®ion, 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