summaryrefslogtreecommitdiff
path: root/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
diff options
context:
space:
mode:
authorErich Keane <ekeane@nvidia.com>2025-08-18 06:33:40 -0700
committerGitHub <noreply@github.com>2025-08-18 06:33:40 -0700
commit340fa3e1bb723de53e9074f50aed13eb15820b47 (patch)
tree9c63bbff89d0c18832c754ae0e14f3a7d88304fb /clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
parent1650e4a73c4363a7a98a29c9a181dee57ce0ba64 (diff)
[OpenACC] Implement firstprivate lowering except init. (#153847)
This patch implements the basic lowering infrastructure, but does not quite implement the copy initialization, which requires #153622. It does however pass verification for the 'copy' section, which just contains a yield.
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp74
1 files changed, 57 insertions, 17 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
index 9194b522114b..72e2c533254c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
@@ -387,6 +387,20 @@ class OpenACCClauseCIREmitter final
return recipeName;
}
+ void createFirstprivateRecipeCopy(
+ mlir::Location loc, mlir::Location locEnd, mlir::Value mainOp,
+ CIRGenFunction::AutoVarEmission tempDeclEmission,
+ mlir::acc::FirstprivateRecipeOp recipe, const VarDecl *varRecipe,
+ const VarDecl *temporary) {
+ builder.createBlock(&recipe.getCopyRegion(), recipe.getCopyRegion().end(),
+ {mainOp.getType(), mainOp.getType()}, {loc, loc});
+ builder.setInsertionPointToEnd(&recipe.getCopyRegion().back());
+
+ // TODO: OpenACC: Implement this copy to actually do something.
+
+ mlir::acc::YieldOp::create(builder, locEnd);
+ }
+
// Create the 'init' section of the recipe, including the 'copy' section for
// 'firstprivate'.
template <typename RecipeTy>
@@ -401,12 +415,6 @@ class OpenACCClauseCIREmitter final
cgf.cgm.errorNYI(exprRange, "OpenACC Reduction recipe init");
}
- if constexpr (std::is_same_v<RecipeTy, mlir::acc::FirstprivateRecipeOp>) {
- // We haven't implemented the 'init'/copy recipe for firstprivate yet, so
- // NYI it.
- cgf.cgm.errorNYI(exprRange, "OpenACC firstprivate recipe init");
- }
-
CIRGenFunction::AutoVarEmission tempDeclEmission{
CIRGenFunction::AutoVarEmission::invalid()};
@@ -442,17 +450,12 @@ class OpenACCClauseCIREmitter final
mlir::acc::YieldOp::create(builder, locEnd);
if constexpr (std::is_same_v<RecipeTy, mlir::acc::FirstprivateRecipeOp>) {
- if (!varRecipe->getInit()) {
- // If we don't have any initialization recipe, we failed during Sema to
- // initialize this correctly. If we disable the
- // Sema::TentativeAnalysisScopes in SemaOpenACC::CreateInitRecipe, it'll
- // emit an error to tell us. However, emitting those errors during
- // production is a violation of the standard, so we cannot do them.
- cgf.cgm.errorNYI(
- exprRange, "firstprivate copy-init recipe not properly generated");
- }
-
- cgf.cgm.errorNYI(exprRange, "firstprivate copy section generation");
+ // TODO: OpenACC: we should have a errorNYI call here if
+ // !varRecipe->getInit(), but as that generation isn't currently
+ // implemented, it ends up being too noisy. So when we implement copy-init
+ // generation both in Sema and here, we should have a diagnostic here.
+ createFirstprivateRecipeCopy(loc, locEnd, mainOp, tempDeclEmission,
+ recipe, varRecipe, temporary);
}
// Make sure we cleanup after ourselves here.
@@ -1155,6 +1158,43 @@ public:
llvm_unreachable("Unknown construct kind in VisitPrivateClause");
}
}
+
+ void VisitFirstPrivateClause(const OpenACCFirstPrivateClause &clause) {
+ if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp,
+ mlir::acc::SerialOp>) {
+ for (const auto [varExpr, varRecipe] :
+ llvm::zip_equal(clause.getVarList(), clause.getInitRecipes())) {
+ CIRGenFunction::OpenACCDataOperandInfo opInfo =
+ cgf.getOpenACCDataOperandInfo(varExpr);
+ auto firstPrivateOp = mlir::acc::FirstprivateOp::create(
+ builder, opInfo.beginLoc, opInfo.varValue, /*structured=*/true,
+ /*implicit=*/false, opInfo.name, opInfo.bounds);
+
+ firstPrivateOp.setDataClause(mlir::acc::DataClause::acc_firstprivate);
+
+ {
+ mlir::OpBuilder::InsertionGuard guardCase(builder);
+ auto recipe = getOrCreateRecipe<mlir::acc::FirstprivateRecipeOp>(
+ cgf.getContext(), varExpr, varRecipe.RecipeDecl,
+ varRecipe.InitFromTemporary,
+ Decl::castToDeclContext(cgf.curFuncDecl), opInfo.baseType,
+ firstPrivateOp.getResult());
+
+ // TODO: OpenACC: The dialect is going to change in the near future to
+ // have these be on a different operation, so when that changes, we
+ // probably need to change these here.
+ operation.addFirstPrivatization(builder.getContext(), firstPrivateOp,
+ recipe);
+ }
+ }
+ } else if constexpr (isCombinedType<OpTy>) {
+ // Unlike 'private', 'firstprivate' applies to the compute op, not the
+ // loop op.
+ applyToComputeOp(clause);
+ } else {
+ llvm_unreachable("Unknown construct kind in VisitFirstPrivateClause");
+ }
+ }
};
template <typename OpTy>