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
