https://github.com/erichkeane updated 
https://github.com/llvm/llvm-project/pull/172308

>From 7798a92b988758b147d212c1719dbfabff5053b4 Mon Sep 17 00:00:00 2001
From: erichkeane <[email protected]>
Date: Fri, 12 Dec 2025 07:14:17 -0800
Subject: [PATCH 1/2] [OpenMP][CIR] Implement basic 'parallel' lowering + some
 clause infra

This patch adds some basic lowering for the OMP 'parallel' lowering,
which adds an omp.parallel operation, plus tries to insert into its
region, with a omp.terminator operation..  However, this patch doesn't
implement CapturedStmt (and I don't intend to do so at all), so there
is an NYI error when emitting a parallel region (plus it shows up in IR
    as 'empty'.

This patch also adds some infrastructure to 'lower' clauses, however no
clauses are emitted, and this simply adds a 'not yet implemented'
warning any time a clause is attempted. The OMP clause visitor seems to
have had a bug with how it 'degraded' when a clause wasn't handled (it
  would result in an infinite recursion if it wasn't supplied), so this
fixes that as well.

A followup patch or two may use this infrastructure to demonstrate how
to use it.
---
 clang/include/clang/AST/OpenMPClause.h        |  6 +-
 clang/lib/CIR/CodeGen/CIRGenFunction.h        |  4 ++
 clang/lib/CIR/CodeGen/CIRGenOpenMPClause.cpp  | 63 +++++++++++++++++++
 clang/lib/CIR/CodeGen/CIRGenStmtOpenMP.cpp    | 31 ++++++++-
 clang/lib/CIR/CodeGen/CMakeLists.txt          |  1 +
 .../CIR/CodeGenOpenMP/not-yet-implemented.c   |  5 +-
 clang/test/CIR/CodeGenOpenMP/parallel.c       | 32 ++++++++++
 7 files changed, 137 insertions(+), 5 deletions(-)
 create mode 100644 clang/lib/CIR/CodeGen/CIRGenOpenMPClause.cpp
 create mode 100644 clang/test/CIR/CodeGenOpenMP/parallel.c

diff --git a/clang/include/clang/AST/OpenMPClause.h 
b/clang/include/clang/AST/OpenMPClause.h
index d9c3cf239451e..6525e64ff102f 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -9527,7 +9527,9 @@ class OMPClauseVisitorBase {
 
 #define GEN_CLANG_CLAUSE_CLASS
 #define CLAUSE_CLASS(Enum, Str, Class)                                         
\
-  RetTy Visit##Class(PTR(Class) S) { DISPATCH(Class); }
+  RetTy Visit##Class(PTR(Class) S) {                                           
\
+    return static_cast<ImplClass *>(this)->VisitOMPClause(S);                  
\
+  }
 #include "llvm/Frontend/OpenMP/OMP.inc"
 
   RetTy Visit(PTR(OMPClause) S) {
@@ -9536,7 +9538,7 @@ class OMPClauseVisitorBase {
 #define GEN_CLANG_CLAUSE_CLASS
 #define CLAUSE_CLASS(Enum, Str, Class)                                         
\
   case llvm::omp::Clause::Enum:                                                
\
-    return Visit##Class(static_cast<PTR(Class)>(S));
+    DISPATCH(Class);
 #define CLAUSE_NO_CLASS(Enum, Str)                                             
\
   case llvm::omp::Clause::Enum:                                                
\
     break;
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index cfe9b37c2c725..a2023caf36d3b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -2155,6 +2155,10 @@ class CIRGenFunction : public CIRGenTypeCache {
   void emitOMPDeclareMapper(const OMPDeclareMapperDecl &d);
   void emitOMPRequiresDecl(const OMPRequiresDecl &d);
 
+private:
+  template <typename Op>
+  void emitOpenMPClauses(Op &op, ArrayRef<const OMPClause *> clauses);
+
   
//===--------------------------------------------------------------------===//
   //                         OpenACC Emission
   
//===--------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenMPClause.cpp 
b/clang/lib/CIR/CodeGen/CIRGenOpenMPClause.cpp
new file mode 100644
index 0000000000000..f73c0c4000d7e
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenMPClause.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Emit OpenMP clause nodes as CIR code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIRGenFunction.h"
+#include "mlir/Dialect/OpenMP/OpenMPDialect.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 ",
+                     clause->getClauseKind());
+  }
+
+  void emitClauses(ArrayRef<const OMPClause *> clauses) {
+    for (const auto *c : clauses)
+      this->Visit(c);
+  }
+};
+template <typename OpTy>
+auto makeClauseEmitter(OpTy &op, CIRGen::CIRGenFunction &cgf,
+                       CIRGen::CIRGenBuilderTy &builder) {
+  return OpenMPClauseCIREmitter<OpTy>(op, cgf, builder);
+}
+} // namespace
+
+template <typename Op>
+void CIRGenFunction::emitOpenMPClauses(Op &op,
+                                       ArrayRef<const OMPClause *> clauses) {
+  mlir::OpBuilder::InsertionGuard guardCase(builder);
+  builder.setInsertionPoint(op);
+  makeClauseEmitter(op, *this, builder).emitClauses(clauses);
+}
+
+// We're defining the template for this in a .cpp file, so we have to 
explicitly
+// specialize the templates.
+#define EXPL_SPEC(N)                                                           
\
+  template void CIRGenFunction::emitOpenMPClauses<N>(                          
\
+      N &, ArrayRef<const OMPClause *>);
+EXPL_SPEC(mlir::omp::ParallelOp)
+#undef EXPL_SPEC
diff --git a/clang/lib/CIR/CodeGen/CIRGenStmtOpenMP.cpp 
b/clang/lib/CIR/CodeGen/CIRGenStmtOpenMP.cpp
index 7fb2dd085acd3..e0de6336a7059 100644
--- a/clang/lib/CIR/CodeGen/CIRGenStmtOpenMP.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenStmtOpenMP.cpp
@@ -30,8 +30,35 @@ CIRGenFunction::emitOMPErrorDirective(const 
OMPErrorDirective &s) {
 }
 mlir::LogicalResult
 CIRGenFunction::emitOMPParallelDirective(const OMPParallelDirective &s) {
-  getCIRGenModule().errorNYI(s.getSourceRange(), "OpenMP 
OMPParallelDirective");
-  return mlir::failure();
+  mlir::LogicalResult res = mlir::success();
+  llvm::SmallVector<mlir::Type> retTy;
+  llvm::SmallVector<mlir::Value> operands;
+  mlir::Location begin = getLoc(s.getBeginLoc());
+  mlir::Location end = getLoc(s.getEndLoc());
+
+  auto parallelOp =
+      mlir::omp::ParallelOp::create(builder, begin, retTy, operands);
+  emitOpenMPClauses(parallelOp, s.clauses());
+
+  {
+    mlir::Block &block = parallelOp.getRegion().emplaceBlock();
+    mlir::OpBuilder::InsertionGuard guardCase(builder);
+    builder.setInsertionPointToEnd(&block);
+
+    LexicalScope ls{*this, begin, builder.getInsertionBlock()};
+
+    if (s.hasCancel())
+      getCIRGenModule().errorNYI(s.getBeginLoc(),
+                                 "OpenMP Parallel with Cancel");
+    if (s.getTaskReductionRefExpr())
+      getCIRGenModule().errorNYI(s.getBeginLoc(),
+                                 "OpenMP Parallel with Task Reduction");
+
+    res = emitStmt(s.getAssociatedStmt(), /*useCurrentScope=*/true);
+
+    mlir::omp::TerminatorOp::create(builder, end);
+  }
+  return res;
 }
 
 mlir::LogicalResult
diff --git a/clang/lib/CIR/CodeGen/CMakeLists.txt 
b/clang/lib/CIR/CodeGen/CMakeLists.txt
index 9ed29cca6a2c6..8efa587f31aac 100644
--- a/clang/lib/CIR/CodeGen/CMakeLists.txt
+++ b/clang/lib/CIR/CodeGen/CMakeLists.txt
@@ -37,6 +37,7 @@ add_clang_library(clangCIR
   CIRGenOpenACC.cpp
   CIRGenOpenACCClause.cpp
   CIRGenOpenACCRecipe.cpp
+  CIRGenOpenMPClause.cpp
   CIRGenPointerAuth.cpp
   CIRGenRecordLayoutBuilder.cpp
   CIRGenStmt.cpp
diff --git a/clang/test/CIR/CodeGenOpenMP/not-yet-implemented.c 
b/clang/test/CIR/CodeGenOpenMP/not-yet-implemented.c
index 171b2b73d1607..e957642d3002e 100644
--- a/clang/test/CIR/CodeGenOpenMP/not-yet-implemented.c
+++ b/clang/test/CIR/CodeGenOpenMP/not-yet-implemented.c
@@ -10,7 +10,10 @@ void do_things() {
   {}
 
   int i;
-  // expected-error@+1{{ClangIR code gen Not Yet Implemented: OpenMP 
OMPParallelDirective}}
+  // TODO(OMP): We might consider overloading operator<< for OMPClauseKind inx
+  // the future if we want to improve this.
+  // expected-error@+2{{ClangIR code gen Not Yet Implemented: OpenMPClause : 
50}}
+  // expected-error@+2{{ClangIR code gen Not Yet Implemented: emitStmt: 
CapturedStmt}}
 #pragma omp parallel if(i)
   {}
 }
diff --git a/clang/test/CIR/CodeGenOpenMP/parallel.c 
b/clang/test/CIR/CodeGenOpenMP/parallel.c
new file mode 100644
index 0000000000000..181ff2872d592
--- /dev/null
+++ b/clang/test/CIR/CodeGenOpenMP/parallel.c
@@ -0,0 +1,32 @@
+// RUN: not %clang_cc1 -fopenmp -emit-cir -fclangir %s -o - | FileCheck %s
+
+void before(int);
+void during(int);
+void after(int);
+
+void emit_simple_parallel() {
+  // CHECK: cir.func{{.*}}@emit_simple_parallel
+  int i = 5;
+  before(i);
+  // CHECK: %[[I_LOAD:.*]] = cir.load{{.*}}
+  // CHECK-NEXT: cir.call @before(%[[I_LOAD]])
+
+#pragma omp parallel
+  {}
+  // CHECK-NEXT: omp.parallel {
+  // CHECK-NEXT: omp.terminator
+  // CHECK-NEXT: }
+#pragma omp parallel
+  {
+    // TODO(OMP): We don't yet emit captured stmt, so the body of this is 
lost,x
+    // thus we don't emit the 'during' call.
+    during(i);
+  }
+  // CHECK-NEXT: omp.parallel {
+  // CHECK-NEXT: omp.terminator
+  // CHECK-NEXT: }
+
+  after(i);
+  // CHECK: %[[I_LOAD:.*]] = cir.load{{.*}}
+  // CHECK-NEXT: cir.call @after(%[[I_LOAD]])
+}

>From 266b9e84b83331931b03c7f92b14201d6ab65dc1 Mon Sep 17 00:00:00 2001
From: erichkeane <[email protected]>
Date: Mon, 15 Dec 2025 06:45:27 -0800
Subject: [PATCH 2/2] Fix typo

---
 clang/test/CIR/CodeGenOpenMP/not-yet-implemented.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/CIR/CodeGenOpenMP/not-yet-implemented.c 
b/clang/test/CIR/CodeGenOpenMP/not-yet-implemented.c
index e957642d3002e..20b7b2c4b26b4 100644
--- a/clang/test/CIR/CodeGenOpenMP/not-yet-implemented.c
+++ b/clang/test/CIR/CodeGenOpenMP/not-yet-implemented.c
@@ -10,7 +10,7 @@ void do_things() {
   {}
 
   int i;
-  // TODO(OMP): We might consider overloading operator<< for OMPClauseKind inx
+  // TODO(OMP): We might consider overloading operator<< for OMPClauseKind in
   // the future if we want to improve this.
   // expected-error@+2{{ClangIR code gen Not Yet Implemented: OpenMPClause : 
50}}
   // expected-error@+2{{ClangIR code gen Not Yet Implemented: emitStmt: 
CapturedStmt}}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to