diff --git a/mlir/include/mlir/Target/LLVMIR/LLVMTranslationInterface.h b/mlir/include/mlir/Target/LLVMIR/LLVMTranslationInterface.h --- a/mlir/include/mlir/Target/LLVMIR/LLVMTranslationInterface.h +++ b/mlir/include/mlir/Target/LLVMIR/LLVMTranslationInterface.h @@ -45,6 +45,14 @@ return failure(); } + /// Hook for derived dialect interface to provide translation of module + /// type operations to LLVM IR where special handling is neccessary. + virtual LogicalResult + convertModuleOperation(Operation *op, llvm::IRBuilderBase &builder, + LLVM::ModuleTranslation &moduleTranslation) const { + return success(); + } + /// Hook for derived dialect interface to act on an operation that has dialect /// attributes from the derived dialect (the operation itself may be from a /// different dialect). This gets called after the operation has been @@ -75,6 +83,17 @@ return failure(); } + /// Translates the given module operation to LLVM IR using the interface + /// implemented by the op's dialect. This is invoked after all operations + /// within the module have been processed. + virtual LogicalResult + convertModuleOperation(Operation *op, llvm::IRBuilderBase &builder, + LLVM::ModuleTranslation &moduleTranslation) const { + if (const LLVMTranslationDialectInterface *iface = getInterfaceFor(op)) + return iface->convertModuleOperation(op, builder, moduleTranslation); + return success(); + } + /// Acts on the given operation using the interface implemented by the dialect /// of one of the operation's dialect attributes. virtual LogicalResult diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h --- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h +++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h @@ -273,6 +273,13 @@ LogicalResult convertGlobals(); LogicalResult convertOneFunction(LLVMFuncOp func); + /// Converts a module operation after all other operations have been handled. + /// This is a No-Op for dialects that have no specified interface for module + /// operations or attributes. This function is invoked after all operations + /// in the module have been processed. + LogicalResult convertModuleOperation(Operation &op, + llvm::IRBuilderBase &builder); + /// Process access_group LLVM Metadata operations and create LLVM /// metadata nodes. LogicalResult createAccessGroupMetadata(); diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -565,6 +565,22 @@ return builder.CreateCall(fn, args); } +/// Given a single MLIR module, create the corresponding LLVM IR operations +/// using the `builder`, this lowering is defined by the dialect and for dialect +/// specific modules e.g. omp.module from the OpenMP dialect. This is a +/// completely optional hook for a dialect. This function is invoked after all +/// operations in the module have been processed. +LogicalResult +ModuleTranslation::convertModuleOperation(Operation &op, + llvm::IRBuilderBase &builder) { + if (const LLVMTranslationDialectInterface *opIface = + iface.getInterfaceFor(&op)) { + if (failed(opIface->convertModuleOperation(&op, builder, *this))) + return failure(); + } + return convertDialectAttributes(&op); +} + /// Given a single MLIR operation, create the corresponding LLVM IR operation /// using the `builder`. LogicalResult @@ -1332,6 +1348,11 @@ } } + // Convert a dialect specific module and it's attributes with dialect + // specific lowering if neccessary, otherwise this is a no-op + if (failed(translator.convertModuleOperation(*module, llvmBuilder))) + return nullptr; + if (llvm::verifyModule(*translator.llvmModule, &llvm::errs())) return nullptr;