Author: erichkeane
Date: 2025-04-28T07:59:12-07:00
New Revision: 258e1438c23c20cfe5c4908633401ab0adf4a364

URL: 
https://github.com/llvm/llvm-project/commit/258e1438c23c20cfe5c4908633401ab0adf4a364
DIFF: 
https://github.com/llvm/llvm-project/commit/258e1438c23c20cfe5c4908633401ab0adf4a364.diff

LOG: [OpenACC][CIR][NFC] Refactor to move 'loop' emit into its own file

The 'loop' emit for OpenACC is particularly complicated/involved, so it
makes sense to be in its own file. This patch splits it out into its own
file, as well as the clause emitter code (as loop is going to require
    that).

Added: 
    clang/lib/CIR/CodeGen/CIRGenOpenACCClause.h
    clang/lib/CIR/CodeGen/CIRGenStmtOpenACCLoop.cpp

Modified: 
    clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp
    clang/lib/CIR/CodeGen/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.h 
b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.h
new file mode 100644
index 0000000000000..b54682402d961
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.h
@@ -0,0 +1,318 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 OpenACC clause nodes as CIR code.
+//
+//===----------------------------------------------------------------------===//
+
+#include <type_traits>
+
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+namespace clang {
+// Simple type-trait to see if the first template arg is one of the list, so we
+// can tell whether to `if-constexpr` a bunch of stuff.
+template <typename ToTest, typename T, typename... Tys>
+constexpr bool isOneOfTypes =
+    std::is_same_v<ToTest, T> || isOneOfTypes<ToTest, Tys...>;
+template <typename ToTest, typename T>
+constexpr bool isOneOfTypes<ToTest, T> = std::is_same_v<ToTest, T>;
+
+template <typename OpTy>
+class OpenACCClauseCIREmitter final
+    : public OpenACCClauseVisitor<OpenACCClauseCIREmitter<OpTy>> {
+  OpTy &operation;
+  CIRGen::CIRGenFunction &cgf;
+  CIRGen::CIRGenBuilderTy &builder;
+
+  // This is necessary since a few of the clauses emit 
diff erently based on the
+  // directive kind they are attached to.
+  OpenACCDirectiveKind dirKind;
+  // TODO(cir): This source location should be able to go away once the NYI
+  // diagnostics are gone.
+  SourceLocation dirLoc;
+
+  llvm::SmallVector<mlir::acc::DeviceType> lastDeviceTypeValues;
+
+  void setLastDeviceTypeClause(const OpenACCDeviceTypeClause &clause) {
+    lastDeviceTypeValues.clear();
+
+    llvm::for_each(clause.getArchitectures(),
+                   [this](const DeviceTypeArgument &arg) {
+                     lastDeviceTypeValues.push_back(
+                         decodeDeviceType(arg.getIdentifierInfo()));
+                   });
+  }
+
+  void clauseNotImplemented(const OpenACCClause &c) {
+    cgf.cgm.errorNYI(c.getSourceRange(), "OpenACC Clause", c.getClauseKind());
+  }
+
+  mlir::Value createIntExpr(const Expr *intExpr) {
+    mlir::Value expr = cgf.emitScalarExpr(intExpr);
+    mlir::Location exprLoc = cgf.cgm.getLoc(intExpr->getBeginLoc());
+
+    mlir::IntegerType targetType = mlir::IntegerType::get(
+        &cgf.getMLIRContext(), 
cgf.getContext().getIntWidth(intExpr->getType()),
+        intExpr->getType()->isSignedIntegerOrEnumerationType()
+            ? mlir::IntegerType::SignednessSemantics::Signed
+            : mlir::IntegerType::SignednessSemantics::Unsigned);
+
+    auto conversionOp = builder.create<mlir::UnrealizedConversionCastOp>(
+        exprLoc, targetType, expr);
+    return conversionOp.getResult(0);
+  }
+
+  // 'condition' as an OpenACC grammar production is used for 'if' and (some
+  // variants of) 'self'.  It needs to be emitted as a signless-1-bit value, so
+  // this function emits the expression, then sets the unrealized conversion
+  // cast correctly, and returns the completed value.
+  mlir::Value createCondition(const Expr *condExpr) {
+    mlir::Value condition = cgf.evaluateExprAsBool(condExpr);
+    mlir::Location exprLoc = cgf.cgm.getLoc(condExpr->getBeginLoc());
+    mlir::IntegerType targetType = mlir::IntegerType::get(
+        &cgf.getMLIRContext(), /*width=*/1,
+        mlir::IntegerType::SignednessSemantics::Signless);
+    auto conversionOp = builder.create<mlir::UnrealizedConversionCastOp>(
+        exprLoc, targetType, condition);
+    return conversionOp.getResult(0);
+  }
+
+  mlir::acc::DeviceType decodeDeviceType(const IdentifierInfo *ii) {
+    // '*' case leaves no identifier-info, just a nullptr.
+    if (!ii)
+      return mlir::acc::DeviceType::Star;
+    return llvm::StringSwitch<mlir::acc::DeviceType>(ii->getName())
+        .CaseLower("default", mlir::acc::DeviceType::Default)
+        .CaseLower("host", mlir::acc::DeviceType::Host)
+        .CaseLower("multicore", mlir::acc::DeviceType::Multicore)
+        .CasesLower("nvidia", "acc_device_nvidia",
+                    mlir::acc::DeviceType::Nvidia)
+        .CaseLower("radeon", mlir::acc::DeviceType::Radeon);
+  }
+
+public:
+  OpenACCClauseCIREmitter(OpTy &operation, CIRGen::CIRGenFunction &cgf,
+                          CIRGen::CIRGenBuilderTy &builder,
+                          OpenACCDirectiveKind dirKind, SourceLocation dirLoc)
+      : operation(operation), cgf(cgf), builder(builder), dirKind(dirKind),
+        dirLoc(dirLoc) {}
+
+  void VisitClause(const OpenACCClause &clause) {
+    clauseNotImplemented(clause);
+  }
+
+  void VisitDefaultClause(const OpenACCDefaultClause &clause) {
+    // This type-trait checks if 'op'(the first arg) is one of the mlir::acc
+    // operations listed in the rest of the arguments.
+    if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp, 
mlir::acc::SerialOp,
+                               mlir::acc::KernelsOp, mlir::acc::DataOp>) {
+      switch (clause.getDefaultClauseKind()) {
+      case OpenACCDefaultClauseKind::None:
+        operation.setDefaultAttr(mlir::acc::ClauseDefaultValue::None);
+        break;
+      case OpenACCDefaultClauseKind::Present:
+        operation.setDefaultAttr(mlir::acc::ClauseDefaultValue::Present);
+        break;
+      case OpenACCDefaultClauseKind::Invalid:
+        break;
+      }
+    } else {
+      // TODO: When we've implemented this for everything, switch this to an
+      // unreachable. Combined constructs remain.
+      return clauseNotImplemented(clause);
+    }
+  }
+
+  void VisitDeviceTypeClause(const OpenACCDeviceTypeClause &clause) {
+    setLastDeviceTypeClause(clause);
+
+    if constexpr (isOneOfTypes<OpTy, mlir::acc::InitOp,
+                               mlir::acc::ShutdownOp>) {
+      llvm::for_each(
+          clause.getArchitectures(), [this](const DeviceTypeArgument &arg) {
+            operation.addDeviceType(builder.getContext(),
+                                    decodeDeviceType(arg.getIdentifierInfo()));
+          });
+    } else if constexpr (isOneOfTypes<OpTy, mlir::acc::SetOp>) {
+      assert(!operation.getDeviceTypeAttr() && "already have device-type?");
+      assert(clause.getArchitectures().size() <= 1);
+
+      if (!clause.getArchitectures().empty())
+        operation.setDeviceType(
+            
decodeDeviceType(clause.getArchitectures()[0].getIdentifierInfo()));
+    } else if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp,
+                                      mlir::acc::SerialOp, 
mlir::acc::KernelsOp,
+                                      mlir::acc::DataOp>) {
+      // Nothing to do here, these constructs don't have any IR for these, as
+      // they just modify the other clauses IR.  So setting of
+      // `lastDeviceTypeValues` (done above) is all we need.
+    } else {
+      // TODO: When we've implemented this for everything, switch this to an
+      // unreachable. update, data, loop, routine, combined constructs remain.
+      return clauseNotImplemented(clause);
+    }
+  }
+
+  void VisitNumWorkersClause(const OpenACCNumWorkersClause &clause) {
+    if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp,
+                               mlir::acc::KernelsOp>) {
+      operation.addNumWorkersOperand(builder.getContext(),
+                                     createIntExpr(clause.getIntExpr()),
+                                     lastDeviceTypeValues);
+    } else if constexpr (isOneOfTypes<OpTy, mlir::acc::SerialOp>) {
+      llvm_unreachable("num_workers not valid on serial");
+    } else {
+      // TODO: When we've implemented this for everything, switch this to an
+      // unreachable. Combined constructs remain.
+      return clauseNotImplemented(clause);
+    }
+  }
+
+  void VisitVectorLengthClause(const OpenACCVectorLengthClause &clause) {
+    if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp,
+                               mlir::acc::KernelsOp>) {
+      operation.addVectorLengthOperand(builder.getContext(),
+                                       createIntExpr(clause.getIntExpr()),
+                                       lastDeviceTypeValues);
+    } else if constexpr (isOneOfTypes<OpTy, mlir::acc::SerialOp>) {
+      llvm_unreachable("vector_length not valid on serial");
+    } else {
+      // TODO: When we've implemented this for everything, switch this to an
+      // unreachable. Combined constructs remain.
+      return clauseNotImplemented(clause);
+    }
+  }
+
+  void VisitAsyncClause(const OpenACCAsyncClause &clause) {
+    if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp, 
mlir::acc::SerialOp,
+                               mlir::acc::KernelsOp, mlir::acc::DataOp>) {
+      if (!clause.hasIntExpr())
+        operation.addAsyncOnly(builder.getContext(), lastDeviceTypeValues);
+      else
+        operation.addAsyncOperand(builder.getContext(),
+                                  createIntExpr(clause.getIntExpr()),
+                                  lastDeviceTypeValues);
+    } else if constexpr (isOneOfTypes<OpTy, mlir::acc::WaitOp>) {
+      // Wait doesn't have a device_type, so its handling here is slightly
+      // 
diff erent.
+      if (!clause.hasIntExpr())
+        operation.setAsync(true);
+      else
+        operation.getAsyncOperandMutable().append(
+            createIntExpr(clause.getIntExpr()));
+    } else {
+      // TODO: When we've implemented this for everything, switch this to an
+      // unreachable. Combined constructs remain. Data, enter data, exit data,
+      // update, combined constructs remain.
+      return clauseNotImplemented(clause);
+    }
+  }
+
+  void VisitSelfClause(const OpenACCSelfClause &clause) {
+    if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp, 
mlir::acc::SerialOp,
+                               mlir::acc::KernelsOp>) {
+      if (clause.isEmptySelfClause()) {
+        operation.setSelfAttr(true);
+      } else if (clause.isConditionExprClause()) {
+        assert(clause.hasConditionExpr());
+        operation.getSelfCondMutable().append(
+            createCondition(clause.getConditionExpr()));
+      } else {
+        llvm_unreachable("var-list version of self shouldn't get here");
+      }
+    } else {
+      // TODO: When we've implemented this for everything, switch this to an
+      // unreachable. If, combined constructs remain.
+      return clauseNotImplemented(clause);
+    }
+  }
+
+  void VisitIfClause(const OpenACCIfClause &clause) {
+    if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp, 
mlir::acc::SerialOp,
+                               mlir::acc::KernelsOp, mlir::acc::InitOp,
+                               mlir::acc::ShutdownOp, mlir::acc::SetOp,
+                               mlir::acc::DataOp, mlir::acc::WaitOp>) {
+      operation.getIfCondMutable().append(
+          createCondition(clause.getConditionExpr()));
+    } else {
+      // 'if' applies to most of the constructs, but hold off on lowering them
+      // until we can write tests/know what we're doing with codegen to make
+      // sure we get it right.
+      // TODO: When we've implemented this for everything, switch this to an
+      // unreachable. Enter data, exit data, host_data, update, combined
+      // constructs remain.
+      return clauseNotImplemented(clause);
+    }
+  }
+
+  void VisitDeviceNumClause(const OpenACCDeviceNumClause &clause) {
+    if constexpr (isOneOfTypes<OpTy, mlir::acc::InitOp, mlir::acc::ShutdownOp,
+                               mlir::acc::SetOp>) {
+      operation.getDeviceNumMutable().append(
+          createIntExpr(clause.getIntExpr()));
+    } else {
+      llvm_unreachable(
+          "init, shutdown, set, are only valid device_num constructs");
+    }
+  }
+
+  void VisitNumGangsClause(const OpenACCNumGangsClause &clause) {
+    if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp,
+                               mlir::acc::KernelsOp>) {
+      llvm::SmallVector<mlir::Value> values;
+      for (const Expr *E : clause.getIntExprs())
+        values.push_back(createIntExpr(E));
+
+      operation.addNumGangsOperands(builder.getContext(), values,
+                                    lastDeviceTypeValues);
+    } else {
+      // TODO: When we've implemented this for everything, switch this to an
+      // unreachable. Combined constructs remain.
+      return clauseNotImplemented(clause);
+    }
+  }
+
+  void VisitWaitClause(const OpenACCWaitClause &clause) {
+    if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp, 
mlir::acc::SerialOp,
+                               mlir::acc::KernelsOp, mlir::acc::DataOp>) {
+      if (!clause.hasExprs()) {
+        operation.addWaitOnly(builder.getContext(), lastDeviceTypeValues);
+      } else {
+        llvm::SmallVector<mlir::Value> values;
+        if (clause.hasDevNumExpr())
+          values.push_back(createIntExpr(clause.getDevNumExpr()));
+        for (const Expr *E : clause.getQueueIdExprs())
+          values.push_back(createIntExpr(E));
+        operation.addWaitOperands(builder.getContext(), clause.hasDevNumExpr(),
+                                  values, lastDeviceTypeValues);
+      }
+    } else {
+      // TODO: When we've implemented this for everything, switch this to an
+      // unreachable. Enter data, exit data, update, Combined constructs 
remain.
+      return clauseNotImplemented(clause);
+    }
+  }
+
+  void VisitDefaultAsyncClause(const OpenACCDefaultAsyncClause &clause) {
+    if constexpr (isOneOfTypes<OpTy, mlir::acc::SetOp>) {
+      operation.getDefaultAsyncMutable().append(
+          createIntExpr(clause.getIntExpr()));
+    } else {
+      llvm_unreachable("set, is only valid device_num constructs");
+    }
+  }
+};
+
+template <typename OpTy>
+auto makeClauseEmitter(OpTy &op, CIRGen::CIRGenFunction &cgf,
+                       CIRGen::CIRGenBuilderTy &builder,
+                       OpenACCDirectiveKind dirKind, SourceLocation dirLoc) {
+  return OpenACCClauseCIREmitter<OpTy>(op, cgf, builder, dirKind, dirLoc);
+}
+
+} // namespace clang

diff  --git a/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp 
b/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp
index 6f86d2b681a1e..fbbbf70ea97c3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp
@@ -9,10 +9,10 @@
 // Emit OpenACC Stmt nodes as CIR code.
 //
 
//===----------------------------------------------------------------------===//
-#include <type_traits>
 
 #include "CIRGenBuilder.h"
 #include "CIRGenFunction.h"
+#include "CIRGenOpenACCClause.h"
 #include "clang/AST/OpenACCClause.h"
 #include "clang/AST/StmtOpenACC.h"
 
@@ -23,297 +23,6 @@ using namespace clang::CIRGen;
 using namespace cir;
 using namespace mlir::acc;
 
-namespace {
-// Simple type-trait to see if the first template arg is one of the list, so we
-// can tell whether to `if-constexpr` a bunch of stuff.
-template <typename ToTest, typename T, typename... Tys>
-constexpr bool isOneOfTypes =
-    std::is_same_v<ToTest, T> || isOneOfTypes<ToTest, Tys...>;
-template <typename ToTest, typename T>
-constexpr bool isOneOfTypes<ToTest, T> = std::is_same_v<ToTest, T>;
-
-template <typename OpTy>
-class OpenACCClauseCIREmitter final
-    : public OpenACCClauseVisitor<OpenACCClauseCIREmitter<OpTy>> {
-  OpTy &operation;
-  CIRGenFunction &cgf;
-  CIRGenBuilderTy &builder;
-
-  // This is necessary since a few of the clauses emit 
diff erently based on the
-  // directive kind they are attached to.
-  OpenACCDirectiveKind dirKind;
-  // TODO(cir): This source location should be able to go away once the NYI
-  // diagnostics are gone.
-  SourceLocation dirLoc;
-
-  llvm::SmallVector<mlir::acc::DeviceType> lastDeviceTypeValues;
-
-  void setLastDeviceTypeClause(const OpenACCDeviceTypeClause &clause) {
-    lastDeviceTypeValues.clear();
-
-    llvm::for_each(clause.getArchitectures(),
-                   [this](const DeviceTypeArgument &arg) {
-                     lastDeviceTypeValues.push_back(
-                         decodeDeviceType(arg.getIdentifierInfo()));
-                   });
-  }
-
-  void clauseNotImplemented(const OpenACCClause &c) {
-    cgf.cgm.errorNYI(c.getSourceRange(), "OpenACC Clause", c.getClauseKind());
-  }
-
-  mlir::Value createIntExpr(const Expr *intExpr) {
-    mlir::Value expr = cgf.emitScalarExpr(intExpr);
-    mlir::Location exprLoc = cgf.cgm.getLoc(intExpr->getBeginLoc());
-
-    mlir::IntegerType targetType = mlir::IntegerType::get(
-        &cgf.getMLIRContext(), 
cgf.getContext().getIntWidth(intExpr->getType()),
-        intExpr->getType()->isSignedIntegerOrEnumerationType()
-            ? mlir::IntegerType::SignednessSemantics::Signed
-            : mlir::IntegerType::SignednessSemantics::Unsigned);
-
-    auto conversionOp = builder.create<mlir::UnrealizedConversionCastOp>(
-        exprLoc, targetType, expr);
-    return conversionOp.getResult(0);
-  }
-
-  // 'condition' as an OpenACC grammar production is used for 'if' and (some
-  // variants of) 'self'.  It needs to be emitted as a signless-1-bit value, so
-  // this function emits the expression, then sets the unrealized conversion
-  // cast correctly, and returns the completed value.
-  mlir::Value createCondition(const Expr *condExpr) {
-    mlir::Value condition = cgf.evaluateExprAsBool(condExpr);
-    mlir::Location exprLoc = cgf.cgm.getLoc(condExpr->getBeginLoc());
-    mlir::IntegerType targetType = mlir::IntegerType::get(
-        &cgf.getMLIRContext(), /*width=*/1,
-        mlir::IntegerType::SignednessSemantics::Signless);
-    auto conversionOp = builder.create<mlir::UnrealizedConversionCastOp>(
-        exprLoc, targetType, condition);
-    return conversionOp.getResult(0);
-  }
-
-  mlir::acc::DeviceType decodeDeviceType(const IdentifierInfo *ii) {
-    // '*' case leaves no identifier-info, just a nullptr.
-    if (!ii)
-      return mlir::acc::DeviceType::Star;
-    return llvm::StringSwitch<mlir::acc::DeviceType>(ii->getName())
-        .CaseLower("default", mlir::acc::DeviceType::Default)
-        .CaseLower("host", mlir::acc::DeviceType::Host)
-        .CaseLower("multicore", mlir::acc::DeviceType::Multicore)
-        .CasesLower("nvidia", "acc_device_nvidia",
-                    mlir::acc::DeviceType::Nvidia)
-        .CaseLower("radeon", mlir::acc::DeviceType::Radeon);
-  }
-
-public:
-  OpenACCClauseCIREmitter(OpTy &operation, CIRGenFunction &cgf,
-                          CIRGenBuilderTy &builder,
-                          OpenACCDirectiveKind dirKind, SourceLocation dirLoc)
-      : operation(operation), cgf(cgf), builder(builder), dirKind(dirKind),
-        dirLoc(dirLoc) {}
-
-  void VisitClause(const OpenACCClause &clause) {
-    clauseNotImplemented(clause);
-  }
-
-  void VisitDefaultClause(const OpenACCDefaultClause &clause) {
-    // This type-trait checks if 'op'(the first arg) is one of the mlir::acc
-    // operations listed in the rest of the arguments.
-    if constexpr (isOneOfTypes<OpTy, ParallelOp, SerialOp, KernelsOp, DataOp>) 
{
-      switch (clause.getDefaultClauseKind()) {
-      case OpenACCDefaultClauseKind::None:
-        operation.setDefaultAttr(ClauseDefaultValue::None);
-        break;
-      case OpenACCDefaultClauseKind::Present:
-        operation.setDefaultAttr(ClauseDefaultValue::Present);
-        break;
-      case OpenACCDefaultClauseKind::Invalid:
-        break;
-      }
-    } else {
-      // TODO: When we've implemented this for everything, switch this to an
-      // unreachable. Combined constructs remain.
-      return clauseNotImplemented(clause);
-    }
-  }
-
-  void VisitDeviceTypeClause(const OpenACCDeviceTypeClause &clause) {
-    setLastDeviceTypeClause(clause);
-
-    if constexpr (isOneOfTypes<OpTy, InitOp, ShutdownOp>) {
-      llvm::for_each(
-          clause.getArchitectures(), [this](const DeviceTypeArgument &arg) {
-            operation.addDeviceType(builder.getContext(),
-                                    decodeDeviceType(arg.getIdentifierInfo()));
-          });
-    } else if constexpr (isOneOfTypes<OpTy, SetOp>) {
-      assert(!operation.getDeviceTypeAttr() && "already have device-type?");
-      assert(clause.getArchitectures().size() <= 1);
-
-      if (!clause.getArchitectures().empty())
-        operation.setDeviceType(
-            
decodeDeviceType(clause.getArchitectures()[0].getIdentifierInfo()));
-    } else if constexpr (isOneOfTypes<OpTy, ParallelOp, SerialOp, KernelsOp,
-                                      DataOp>) {
-      // Nothing to do here, these constructs don't have any IR for these, as
-      // they just modify the other clauses IR.  So setting of
-      // `lastDeviceTypeValues` (done above) is all we need.
-    } else {
-      // TODO: When we've implemented this for everything, switch this to an
-      // unreachable. update, data, loop, routine, combined constructs remain.
-      return clauseNotImplemented(clause);
-    }
-  }
-
-  void VisitNumWorkersClause(const OpenACCNumWorkersClause &clause) {
-    if constexpr (isOneOfTypes<OpTy, ParallelOp, KernelsOp>) {
-      operation.addNumWorkersOperand(builder.getContext(),
-                                     createIntExpr(clause.getIntExpr()),
-                                     lastDeviceTypeValues);
-    } else if constexpr (isOneOfTypes<OpTy, SerialOp>) {
-      llvm_unreachable("num_workers not valid on serial");
-    } else {
-      // TODO: When we've implemented this for everything, switch this to an
-      // unreachable. Combined constructs remain.
-      return clauseNotImplemented(clause);
-    }
-  }
-
-  void VisitVectorLengthClause(const OpenACCVectorLengthClause &clause) {
-    if constexpr (isOneOfTypes<OpTy, ParallelOp, KernelsOp>) {
-      operation.addVectorLengthOperand(builder.getContext(),
-                                       createIntExpr(clause.getIntExpr()),
-                                       lastDeviceTypeValues);
-    } else if constexpr (isOneOfTypes<OpTy, SerialOp>) {
-      llvm_unreachable("vector_length not valid on serial");
-    } else {
-      // TODO: When we've implemented this for everything, switch this to an
-      // unreachable. Combined constructs remain.
-      return clauseNotImplemented(clause);
-    }
-  }
-
-  void VisitAsyncClause(const OpenACCAsyncClause &clause) {
-    if constexpr (isOneOfTypes<OpTy, ParallelOp, SerialOp, KernelsOp, DataOp>) 
{
-      if (!clause.hasIntExpr())
-        operation.addAsyncOnly(builder.getContext(), lastDeviceTypeValues);
-      else
-        operation.addAsyncOperand(builder.getContext(),
-                                  createIntExpr(clause.getIntExpr()),
-                                  lastDeviceTypeValues);
-    } else if constexpr (isOneOfTypes<OpTy, WaitOp>) {
-      // Wait doesn't have a device_type, so its handling here is slightly
-      // 
diff erent.
-      if (!clause.hasIntExpr())
-        operation.setAsync(true);
-      else
-        operation.getAsyncOperandMutable().append(
-            createIntExpr(clause.getIntExpr()));
-    } else {
-      // TODO: When we've implemented this for everything, switch this to an
-      // unreachable. Combined constructs remain. Data, enter data, exit data,
-      // update, combined constructs remain.
-      return clauseNotImplemented(clause);
-    }
-  }
-
-  void VisitSelfClause(const OpenACCSelfClause &clause) {
-    if constexpr (isOneOfTypes<OpTy, ParallelOp, SerialOp, KernelsOp>) {
-      if (clause.isEmptySelfClause()) {
-        operation.setSelfAttr(true);
-      } else if (clause.isConditionExprClause()) {
-        assert(clause.hasConditionExpr());
-        operation.getSelfCondMutable().append(
-            createCondition(clause.getConditionExpr()));
-      } else {
-        llvm_unreachable("var-list version of self shouldn't get here");
-      }
-    } else {
-      // TODO: When we've implemented this for everything, switch this to an
-      // unreachable. If, combined constructs remain.
-      return clauseNotImplemented(clause);
-    }
-  }
-
-  void VisitIfClause(const OpenACCIfClause &clause) {
-    if constexpr (isOneOfTypes<OpTy, ParallelOp, SerialOp, KernelsOp, InitOp,
-                               ShutdownOp, SetOp, DataOp, WaitOp>) {
-      operation.getIfCondMutable().append(
-          createCondition(clause.getConditionExpr()));
-    } else {
-      // 'if' applies to most of the constructs, but hold off on lowering them
-      // until we can write tests/know what we're doing with codegen to make
-      // sure we get it right.
-      // TODO: When we've implemented this for everything, switch this to an
-      // unreachable. Enter data, exit data, host_data, update, combined 
-      // constructs remain.
-      return clauseNotImplemented(clause);
-    }
-  }
-
-  void VisitDeviceNumClause(const OpenACCDeviceNumClause &clause) {
-    if constexpr (isOneOfTypes<OpTy, InitOp, ShutdownOp, SetOp>) {
-      operation.getDeviceNumMutable().append(
-          createIntExpr(clause.getIntExpr()));
-    } else {
-      llvm_unreachable(
-          "init, shutdown, set, are only valid device_num constructs");
-    }
-  }
-
-  void VisitNumGangsClause(const OpenACCNumGangsClause &clause) {
-    if constexpr (isOneOfTypes<OpTy, ParallelOp, KernelsOp>) {
-      llvm::SmallVector<mlir::Value> values;
-      for (const Expr *E : clause.getIntExprs())
-        values.push_back(createIntExpr(E));
-
-      operation.addNumGangsOperands(builder.getContext(), values,
-                                    lastDeviceTypeValues);
-    } else {
-      // TODO: When we've implemented this for everything, switch this to an
-      // unreachable. Combined constructs remain.
-      return clauseNotImplemented(clause);
-    }
-  }
-
-  void VisitWaitClause(const OpenACCWaitClause &clause) {
-    if constexpr (isOneOfTypes<OpTy, ParallelOp, SerialOp, KernelsOp, DataOp>) 
{
-      if (!clause.hasExprs()) {
-        operation.addWaitOnly(builder.getContext(), lastDeviceTypeValues);
-      } else {
-        llvm::SmallVector<mlir::Value> values;
-        if (clause.hasDevNumExpr())
-          values.push_back(createIntExpr(clause.getDevNumExpr()));
-        for (const Expr *E : clause.getQueueIdExprs())
-          values.push_back(createIntExpr(E));
-        operation.addWaitOperands(builder.getContext(), clause.hasDevNumExpr(),
-                                  values, lastDeviceTypeValues);
-      }
-    } else {
-      // TODO: When we've implemented this for everything, switch this to an
-      // unreachable. Enter data, exit data, update, Combined constructs 
remain.
-      return clauseNotImplemented(clause);
-    }
-  }
-
-  void VisitDefaultAsyncClause(const OpenACCDefaultAsyncClause &clause) {
-    if constexpr (isOneOfTypes<OpTy, SetOp>) {
-      operation.getDefaultAsyncMutable().append(
-          createIntExpr(clause.getIntExpr()));
-    } else {
-      llvm_unreachable("set, is only valid device_num constructs");
-    }
-  }
-};
-
-template <typename OpTy>
-auto makeClauseEmitter(OpTy &op, CIRGenFunction &cgf, CIRGenBuilderTy &builder,
-                       OpenACCDirectiveKind dirKind, SourceLocation dirLoc) {
-  return OpenACCClauseCIREmitter<OpTy>(op, cgf, builder, dirKind, dirLoc);
-}
-
-} // namespace
-
 template <typename Op, typename TermOp>
 mlir::LogicalResult CIRGenFunction::emitOpenACCOpAssociatedStmt(
     mlir::Location start, mlir::Location end, OpenACCDirectiveKind dirKind,
@@ -459,11 +168,6 @@ CIRGenFunction::emitOpenACCWaitConstruct(const 
OpenACCWaitConstruct &s) {
   return mlir::success();
 }
 
-mlir::LogicalResult
-CIRGenFunction::emitOpenACCLoopConstruct(const OpenACCLoopConstruct &s) {
-  cgm.errorNYI(s.getSourceRange(), "OpenACC Loop Construct");
-  return mlir::failure();
-}
 mlir::LogicalResult CIRGenFunction::emitOpenACCCombinedConstruct(
     const OpenACCCombinedConstruct &s) {
   cgm.errorNYI(s.getSourceRange(), "OpenACC Combined Construct");

diff  --git a/clang/lib/CIR/CodeGen/CIRGenStmtOpenACCLoop.cpp 
b/clang/lib/CIR/CodeGen/CIRGenStmtOpenACCLoop.cpp
new file mode 100644
index 0000000000000..b01ff85607939
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/CIRGenStmtOpenACCLoop.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 OpenACC Loop Stmt node as CIR code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIRGenBuilder.h"
+#include "CIRGenFunction.h"
+#include "CIRGenOpenACCClause.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "clang/AST/OpenACCClause.h"
+#include "clang/AST/StmtOpenACC.h"
+
+using namespace clang;
+using namespace clang::CIRGen;
+using namespace cir;
+using namespace mlir::acc;
+
+mlir::LogicalResult
+CIRGenFunction::emitOpenACCLoopConstruct(const OpenACCLoopConstruct &s) {
+  cgm.errorNYI(s.getSourceRange(), "OpenACC Loop Construct");
+  return mlir::failure();
+}

diff  --git a/clang/lib/CIR/CodeGen/CMakeLists.txt 
b/clang/lib/CIR/CodeGen/CMakeLists.txt
index 400af0237d588..7a701c3c0b82b 100644
--- a/clang/lib/CIR/CodeGen/CMakeLists.txt
+++ b/clang/lib/CIR/CodeGen/CMakeLists.txt
@@ -21,6 +21,7 @@ add_clang_library(clangCIR
   CIRGenRecordLayoutBuilder.cpp
   CIRGenStmt.cpp
   CIRGenStmtOpenACC.cpp
+  CIRGenStmtOpenACCLoop.cpp
   CIRGenTypes.cpp
   TargetInfo.cpp
 


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to