Index: mlir/examples/toy/Ch6/CMakeLists.txt =================================================================== --- mlir/examples/toy/Ch6/CMakeLists.txt +++ mlir/examples/toy/Ch6/CMakeLists.txt @@ -36,6 +36,8 @@ MLIRExecutionEngine MLIRIR MLIRLLVMIR + MLIROpenMP + LLVMFrontendOpenMP MLIRLoopToStandard MLIRParser MLIRPass @@ -49,5 +51,7 @@ MLIRAffineToStandard MLIRAffineOps MLIRLLVMIR + MLIROpenMP + LLVMFrontendOpenMP MLIRStandardOps ) Index: mlir/examples/toy/Ch7/CMakeLists.txt =================================================================== --- mlir/examples/toy/Ch7/CMakeLists.txt +++ mlir/examples/toy/Ch7/CMakeLists.txt @@ -36,6 +36,8 @@ MLIRExecutionEngine MLIRIR MLIRLLVMIR + MLIROpenMP + LLVMFrontendOpenMP MLIRLoopToStandard MLIRParser MLIRPass @@ -49,5 +51,7 @@ MLIRAffineToStandard MLIRAffineOps MLIRLLVMIR + MLIROpenMP + LLVMFrontendOpenMP MLIRStandardOps ) Index: mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h =================================================================== --- mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h +++ mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h @@ -19,6 +19,7 @@ #include "mlir/IR/Module.h" #include "mlir/IR/Value.h" +#include "llvm/Frontend/OpenMP/OMPIRBuilder.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" @@ -84,6 +85,7 @@ private: /// Check whether the module contains only supported ops directly in its body. static LogicalResult checkSupportedModuleOps(Operation *m); + bool existsOrCreateOpenMPIRBuilder(); LogicalResult convertFunctions(); void convertGlobals(); @@ -97,6 +99,7 @@ // Original and translated module. Operation *mlirModule; std::unique_ptr llvmModule; + std::unique_ptr OMPBuilder; // Mappings between llvm.mlir.global definitions and corresponding globals. DenseMap globalsMapping; Index: mlir/lib/Target/LLVMIR/ModuleTranslation.cpp =================================================================== --- mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -14,20 +14,27 @@ #include "mlir/Target/LLVMIR/ModuleTranslation.h" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" +#include "mlir/Dialect/OpenMP/OpenMPDialect.h" #include "mlir/IR/Attributes.h" #include "mlir/IR/Module.h" #include "mlir/IR/StandardTypes.h" #include "mlir/Support/LLVM.h" #include "llvm/ADT/SetVector.h" +#include "llvm/Frontend/OpenMP/OMPIRBuilder.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Transforms/Utils/Cloning.h" +static llvm::cl::opt enableOpenMP{ + "enable-openmp", llvm::cl::desc("Enable translation of OpenMP dialect Ops"), + llvm::cl::init(false)}; + using namespace mlir; using namespace mlir::LLVM; @@ -332,6 +339,17 @@ return success(); } + if (opInst.getDialect()->getNamespace() == "omp") { + if (existsOrCreateOpenMPIRBuilder()) { + if (dyn_cast(opInst)) { + OMPBuilder->CreateBarrier(builder.saveIP(), llvm::omp::OMPD_barrier); + return success(); + } + return opInst.emitError("unsupported or non-OpenMP operation: ") + << opInst.getName(); + } + } + return opInst.emitError("unsupported or non-LLVM operation: ") << opInst.getName(); } @@ -627,3 +645,16 @@ return llvmModule; } + +bool ModuleTranslation::existsOrCreateOpenMPIRBuilder() { + if (!enableOpenMP) + return false; + + if (!OMPBuilder) { + OMPBuilder = + std::move(std::make_unique(*llvmModule)); + OMPBuilder->initialize(); + } + + return true; +} Index: mlir/test/Target/openmp-llvm.mlir =================================================================== --- /dev/null +++ mlir/test/Target/openmp-llvm.mlir @@ -0,0 +1,11 @@ +// RUN: mlir-translate -enable-openmp -mlir-to-llvmir %s | FileCheck %s + +// CHECK-LABEL: define void @empty() { +// CHECK: [[OMP_THREAD:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @{{[0-9]+}}) +// CHECK-NEXT: call void @__kmpc_barrier(%struct.ident_t* @{{[0-9]+}}, i32 [[OMP_THREAD]]) +// CHECK-NEXT: ret void +// CHECK-NEXT: } +llvm.func @empty() { + omp.barrier + llvm.return +} Index: mlir/tools/mlir-cpu-runner/CMakeLists.txt =================================================================== --- mlir/tools/mlir-cpu-runner/CMakeLists.txt +++ mlir/tools/mlir-cpu-runner/CMakeLists.txt @@ -5,6 +5,8 @@ whole_archive_link(mlir-cpu-runner MLIRAffineOps MLIRLLVMIR + MLIROpenMP + LLVMFrontendOpenMP MLIRTargetLLVMIR MLIRTranslation ) @@ -15,6 +17,8 @@ MLIRIR MLIRJitRunner MLIRLLVMIR + MLIROpenMP + LLVMFrontendOpenMP MLIRParser MLIRTargetLLVMIR MLIRSupport Index: mlir/tools/mlir-translate/CMakeLists.txt =================================================================== --- mlir/tools/mlir-translate/CMakeLists.txt +++ mlir/tools/mlir-translate/CMakeLists.txt @@ -8,6 +8,8 @@ MLIRTargetROCDLIR MLIRTranslation MLIRSupport + MLIROpenMP + LLVMFrontendOpenMP ) add_llvm_executable(mlir-translate mlir-translate.cpp