diff options
| author | Erich Keane <ekeane@nvidia.com> | 2025-08-18 06:33:40 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-18 06:33:40 -0700 |
| commit | 340fa3e1bb723de53e9074f50aed13eb15820b47 (patch) | |
| tree | 9c63bbff89d0c18832c754ae0e14f3a7d88304fb /clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp | |
| parent | 1650e4a73c4363a7a98a29c9a181dee57ce0ba64 (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.cpp | 74 |
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> |
