================
@@ -30,49 +33,102 @@ CIRGenFunction::emitOMPErrorDirective(const 
OMPErrorDirective &s) {
   getCIRGenModule().errorNYI(s.getSourceRange(), "OpenMP OMPErrorDirective");
   return mlir::failure();
 }
-mlir::LogicalResult
-CIRGenFunction::emitOMPParallelDirective(const OMPParallelDirective &s) {
+
+/// Report \p item's synthesized clauses as not-yet-implemented: having no AST
+/// node, they cannot go through the clause emitters.
+static mlir::LogicalResult
+checkSynthesizedClauses(CIRGenFunction &cgf, const OMPExecutableDirective &s,
+                        omp::ConstructQueue::const_iterator item) {
   mlir::LogicalResult res = mlir::success();
-  mlir::Location begin = getLoc(s.getBeginLoc());
-  mlir::Location end = getLoc(s.getEndLoc());
+  for (llvm::omp::Clause synth : item->synthesized) {
+    cgf.getCIRGenModule().errorNYI(s.getSourceRange(),
+                                   (llvm::Twine("OpenMP synthesized '") +
+                                    llvm::omp::getOpenMPClauseName(synth) +
+                                    "' clause from construct decomposition")
+                                       .str());
+    res = mlir::failure();
+  }
+  return res;
+}
 
-  mlir::omp::ParallelOperands clauseOps;
-  OpenMPClauseEmitter ce(*this, getCIRGenModule(), builder, begin, 
s.clauses());
+static mlir::LogicalResult
+emitParallelClauses(CIRGenFunction &cgf, CIRGenModule &cgm,
+                    CIRGenBuilderTy &builder, mlir::Location loc,
+                    llvm::ArrayRef<const OMPClause *> clauses,
+                    mlir::omp::ParallelOperands &clauseOps) {
+  OpenMPClauseEmitter ce(cgf, cgm, builder, loc, clauses);
   ce.emitProcBind(clauseOps);
-  ce.emitNYI</*supported=*/OMPProcBindClause>(
+  return ce.emitNYI</*supported=*/OMPProcBindClause>(
       /*nyi=*/OpenMPNYIClauseList<
           OMPAllocateClause, OMPCopyinClause, OMPDefaultClause,
           OMPFirstprivateClause, OMPIfClause, OMPNumThreadsClause,
           OMPPrivateClause, OMPReductionClause, OMPSharedClause>{},
       llvm::omp::Directive::OMPD_parallel);
+}
+
+template <typename DirectiveTy>
+static mlir::LogicalResult
+emitParallelOp(CIRGenFunction &cgf, const DirectiveTy &s,
+               const omp::ConstructQueue &queue,
+               omp::ConstructQueue::const_iterator item, mlir::Location begin,
+               mlir::Location end, const mlir::omp::ParallelOperands 
&clauseOps,
+               llvm::function_ref<mlir::LogicalResult()> emitBody) {
+  CIRGenBuilderTy &builder = cgf.getBuilder();
+  CIRGenModule &cgm = cgf.getCIRGenModule();
 
   auto parallelOp = mlir::omp::ParallelOp::create(builder, begin, clauseOps);
+  if (!omp::isLastItemInQueue(item, queue))
+    parallelOp.setCombined(true);
+
+  mlir::Block &block = parallelOp.getRegion().emplaceBlock();
+  mlir::OpBuilder::InsertionGuard guard(builder);
+  builder.setInsertionPointToEnd(&block);
+
+  CIRGenFunction::LexicalScope ls{cgf, begin, builder.getInsertionBlock()};
 
-  {
-    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");
-    // Don't lower the captured statement directly since this will be
-    // special-cased depending on the kind of OpenMP directive that is the
-    // parent, also the non-OpenMP context captured statements lowering does
-    // not apply directly.
-    const CapturedStmt *cs = s.getCapturedStmt(llvm::omp::OMPD_parallel);
-    const Stmt *bodyStmt = cs->getCapturedStmt();
-    res = emitStmt(bodyStmt, /*useCurrentScope=*/true);
-    mlir::omp::TerminatorOp::create(builder, end);
+  if (s.hasCancel()) {
+    cgm.errorNYI(s.getBeginLoc(), "OpenMP Parallel with Cancel");
+    return mlir::failure();
   }
+  if (s.getTaskReductionRefExpr()) {
+    cgm.errorNYI(s.getBeginLoc(), "OpenMP Parallel with Task Reduction");
+    return mlir::failure();
+  }
+
+  mlir::LogicalResult res = emitBody();
+  mlir::omp::TerminatorOp::create(builder, end);
   return res;
 }
 
+mlir::LogicalResult
+CIRGenFunction::emitOMPParallelDirective(const OMPParallelDirective &s) {
+  mlir::Location begin = getLoc(s.getBeginLoc());
+  mlir::Location end = getLoc(s.getEndLoc());
+
+  omp::ConstructQueue queue =
+      omp::buildConstructQueue(getContext().getLangOpts().OpenMP, s);
+  omp::ConstructQueue::const_iterator item = queue.begin();
+
+  if (mlir::failed(checkSynthesizedClauses(*this, s, item)))
+    return mlir::failure();
+
+  mlir::omp::ParallelOperands clauseOps;
+  if (mlir::failed(emitParallelClauses(*this, getCIRGenModule(), builder, 
begin,
+                                       item->clauses, clauseOps)))
+    return mlir::failure();
+
+  return emitParallelOp(
+      *this, s, queue, item, begin, end, clauseOps,
+      [&]() -> mlir::LogicalResult {
+        // Don't lower the captured statement directly since this will be
+        // special-cased depending on the kind of OpenMP directive that is the
+        // parent, also the non-OpenMP context captured statements lowering 
does
+        // not apply directly.
----------------
skatrak wrote:

Nit: Maybe it's just me, so feel free to ignore, but I don't quite understand 
this comment. We do call `emitStmt` right away for the captured statement while 
saying we don't lower it directly.

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

Reply via email to