llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Erich Keane (erichkeane)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/172308.diff
7 Files Affected:
- (modified) clang/include/clang/AST/OpenMPClause.h (+4-2)
- (modified) clang/lib/CIR/CodeGen/CIRGenFunction.h (+4)
- (added) clang/lib/CIR/CodeGen/CIRGenOpenMPClause.cpp (+63)
- (modified) clang/lib/CIR/CodeGen/CIRGenStmtOpenMP.cpp (+29-2)
- (modified) clang/lib/CIR/CodeGen/CMakeLists.txt (+1)
- (modified) clang/test/CIR/CodeGenOpenMP/not-yet-implemented.c (+4-1)
- (added) clang/test/CIR/CodeGenOpenMP/parallel.c (+32)
``````````diff
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]])
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/172308
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits