[Mlir-commits] [clang] [mlir] [CIR][OpenMP] Initial implementation of target region support (PR #195452)

Jan Leyonberg llvmlistbot at llvm.org
Tue Jun 23 04:19:18 PDT 2026


================
@@ -6,90 +6,140 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// Emit OpenMP clause nodes as CIR code.
+// OpenMP clause emitter implementation.
 //
 //===----------------------------------------------------------------------===//
 
+#include "CIRGenOpenMPClause.h"
 #include "CIRGenFunction.h"
 #include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "clang/Basic/OpenMPKinds.h"
 
 using namespace clang;
 using namespace clang::CIRGen;
 
-namespace {
-template <typename OpTy>
-class OpenMPClauseCIREmitter final
-    : public ConstOMPClauseVisitor<OpenMPClauseCIREmitter<OpTy>> {
-  OpTy &operation;
-  CIRGen::CIRGenFunction &cgf;
-  CIRGen::CIRGenBuilderTy &builder;
-
-public:
-  OpenMPClauseCIREmitter(OpTy &operation, CIRGen::CIRGenFunction &cgf,
-                         CIRGen::CIRGenBuilderTy &builder)
-      : operation(operation), cgf(cgf), builder(builder) {}
-
-  void VisitOMPClause(const OMPClause *clause) {
-    cgf.cgm.errorNYI(clause->getBeginLoc(), "OpenMPClause ",
-                     llvm::omp::getOpenMPClauseName(clause->getClauseKind()));
+static mlir::omp::ClauseMapFlags
+mapClauseKindToFlags(OpenMPMapClauseKind kind) {
+  switch (kind) {
+  case OMPC_MAP_to:
+    return mlir::omp::ClauseMapFlags::to;
+  case OMPC_MAP_from:
+    return mlir::omp::ClauseMapFlags::from;
+  case OMPC_MAP_tofrom:
+    return mlir::omp::ClauseMapFlags::to | mlir::omp::ClauseMapFlags::from;
+  case OMPC_MAP_alloc:
+  case OMPC_MAP_release:
+    return mlir::omp::ClauseMapFlags::storage;
+  case OMPC_MAP_delete:
+    return mlir::omp::ClauseMapFlags::del;
+  default:
+    return mlir::omp::ClauseMapFlags::none;
   }
+}
 
-  void VisitOMPProcBindClause(const OMPProcBindClause *clause) {
-    if constexpr (std::is_same_v<OpTy, mlir::omp::ParallelOp>) {
-      mlir::omp::ClauseProcBindKind kind;
-      switch (clause->getProcBindKind()) {
-      case llvm::omp::ProcBindKind::OMP_PROC_BIND_master:
-        kind = mlir::omp::ClauseProcBindKind::Master;
-        break;
-      case llvm::omp::ProcBindKind::OMP_PROC_BIND_close:
-        kind = mlir::omp::ClauseProcBindKind::Close;
-        break;
-      case llvm::omp::ProcBindKind::OMP_PROC_BIND_spread:
-        kind = mlir::omp::ClauseProcBindKind::Spread;
-        break;
-      case llvm::omp::ProcBindKind::OMP_PROC_BIND_primary:
-        kind = mlir::omp::ClauseProcBindKind::Primary;
-        break;
-      case llvm::omp::ProcBindKind::OMP_PROC_BIND_default:
-        // 'default' in the classic-codegen does no runtime call/doesn't
-        // really do anything. So this is a no-op, and thus shouldn't change
-        // the IR.
-        return;
-      case llvm::omp::ProcBindKind::OMP_PROC_BIND_unknown:
-        llvm_unreachable("unknown proc-bind kind");
-      }
-      operation.setProcBindKind(kind);
-    } else {
-      cgf.cgm.errorNYI(
-          clause->getBeginLoc(),
-          "OMPProcBindClause unimplemented on this directive kind");
-    }
-  }
+static mlir::Value emitMapInfoForVar(CIRGenFunction &cgf,
+                                     mlir::OpBuilder &builder,
+                                     mlir::Location loc, const VarDecl *vd,
+                                     mlir::omp::ClauseMapFlags mapFlags) {
+  Address addr = cgf.getAddrOfLocalVar(vd);
+  mlir::Value varPtr = addr.getPointer();
+  auto varPtrType = mlir::cast<cir::PointerType>(varPtr.getType());
+  mlir::Type elementType = varPtrType.getPointee();
 
-  void emitClauses(ArrayRef<const OMPClause *> clauses) {
-    for (const auto *c : clauses)
-      this->Visit(c);
+  // Cast to generic pointer if needed.
+  if (varPtrType.getAddrSpace()) {
+    auto genericPtrType =
+        cir::PointerType::get(builder.getContext(), elementType);
+    varPtr = cir::CastOp::create(builder, loc, genericPtrType,
+                                 cir::CastKind::address_space, varPtr);
+    varPtrType = genericPtrType;
   }
-};
-template <typename OpTy>
-auto makeClauseEmitter(OpTy &op, CIRGen::CIRGenFunction &cgf,
-                       CIRGen::CIRGenBuilderTy &builder) {
-  return OpenMPClauseCIREmitter<OpTy>(op, cgf, builder);
+
+  return mlir::omp::MapInfoOp::create(
+      builder, loc,
----------------
jsjodin wrote:

Yes, it is created at the end. The problem with the approach of creating an "empty" op and then fill in the rest was specifically for the target op, because it requires certain inputs that are now known ahead of time, and creating dummy-inputs that need to be cleaned up is less convenient than creating once all the inputs are known. It also follows the same pattern as flang, which makes things easier to maintain if we want to make some changes to the OpenMP dialect in the future.

https://github.com/llvm/llvm-project/pull/195452


More information about the Mlir-commits mailing list