Skip to content

Commit 340fa3e

Browse files
authored
[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.
1 parent 1650e4a commit 340fa3e

File tree

5 files changed

+1226
-20
lines changed

5 files changed

+1226
-20
lines changed

clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,20 @@ class OpenACCClauseCIREmitter final
387387
return recipeName;
388388
}
389389

390+
void createFirstprivateRecipeCopy(
391+
mlir::Location loc, mlir::Location locEnd, mlir::Value mainOp,
392+
CIRGenFunction::AutoVarEmission tempDeclEmission,
393+
mlir::acc::FirstprivateRecipeOp recipe, const VarDecl *varRecipe,
394+
const VarDecl *temporary) {
395+
builder.createBlock(&recipe.getCopyRegion(), recipe.getCopyRegion().end(),
396+
{mainOp.getType(), mainOp.getType()}, {loc, loc});
397+
builder.setInsertionPointToEnd(&recipe.getCopyRegion().back());
398+
399+
// TODO: OpenACC: Implement this copy to actually do something.
400+
401+
mlir::acc::YieldOp::create(builder, locEnd);
402+
}
403+
390404
// Create the 'init' section of the recipe, including the 'copy' section for
391405
// 'firstprivate'.
392406
template <typename RecipeTy>
@@ -401,12 +415,6 @@ class OpenACCClauseCIREmitter final
401415
cgf.cgm.errorNYI(exprRange, "OpenACC Reduction recipe init");
402416
}
403417

404-
if constexpr (std::is_same_v<RecipeTy, mlir::acc::FirstprivateRecipeOp>) {
405-
// We haven't implemented the 'init'/copy recipe for firstprivate yet, so
406-
// NYI it.
407-
cgf.cgm.errorNYI(exprRange, "OpenACC firstprivate recipe init");
408-
}
409-
410418
CIRGenFunction::AutoVarEmission tempDeclEmission{
411419
CIRGenFunction::AutoVarEmission::invalid()};
412420

@@ -442,17 +450,12 @@ class OpenACCClauseCIREmitter final
442450
mlir::acc::YieldOp::create(builder, locEnd);
443451

444452
if constexpr (std::is_same_v<RecipeTy, mlir::acc::FirstprivateRecipeOp>) {
445-
if (!varRecipe->getInit()) {
446-
// If we don't have any initialization recipe, we failed during Sema to
447-
// initialize this correctly. If we disable the
448-
// Sema::TentativeAnalysisScopes in SemaOpenACC::CreateInitRecipe, it'll
449-
// emit an error to tell us. However, emitting those errors during
450-
// production is a violation of the standard, so we cannot do them.
451-
cgf.cgm.errorNYI(
452-
exprRange, "firstprivate copy-init recipe not properly generated");
453-
}
454-
455-
cgf.cgm.errorNYI(exprRange, "firstprivate copy section generation");
453+
// TODO: OpenACC: we should have a errorNYI call here if
454+
// !varRecipe->getInit(), but as that generation isn't currently
455+
// implemented, it ends up being too noisy. So when we implement copy-init
456+
// generation both in Sema and here, we should have a diagnostic here.
457+
createFirstprivateRecipeCopy(loc, locEnd, mainOp, tempDeclEmission,
458+
recipe, varRecipe, temporary);
456459
}
457460

458461
// Make sure we cleanup after ourselves here.
@@ -1155,6 +1158,43 @@ class OpenACCClauseCIREmitter final
11551158
llvm_unreachable("Unknown construct kind in VisitPrivateClause");
11561159
}
11571160
}
1161+
1162+
void VisitFirstPrivateClause(const OpenACCFirstPrivateClause &clause) {
1163+
if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp,
1164+
mlir::acc::SerialOp>) {
1165+
for (const auto [varExpr, varRecipe] :
1166+
llvm::zip_equal(clause.getVarList(), clause.getInitRecipes())) {
1167+
CIRGenFunction::OpenACCDataOperandInfo opInfo =
1168+
cgf.getOpenACCDataOperandInfo(varExpr);
1169+
auto firstPrivateOp = mlir::acc::FirstprivateOp::create(
1170+
builder, opInfo.beginLoc, opInfo.varValue, /*structured=*/true,
1171+
/*implicit=*/false, opInfo.name, opInfo.bounds);
1172+
1173+
firstPrivateOp.setDataClause(mlir::acc::DataClause::acc_firstprivate);
1174+
1175+
{
1176+
mlir::OpBuilder::InsertionGuard guardCase(builder);
1177+
auto recipe = getOrCreateRecipe<mlir::acc::FirstprivateRecipeOp>(
1178+
cgf.getContext(), varExpr, varRecipe.RecipeDecl,
1179+
varRecipe.InitFromTemporary,
1180+
Decl::castToDeclContext(cgf.curFuncDecl), opInfo.baseType,
1181+
firstPrivateOp.getResult());
1182+
1183+
// TODO: OpenACC: The dialect is going to change in the near future to
1184+
// have these be on a different operation, so when that changes, we
1185+
// probably need to change these here.
1186+
operation.addFirstPrivatization(builder.getContext(), firstPrivateOp,
1187+
recipe);
1188+
}
1189+
}
1190+
} else if constexpr (isCombinedType<OpTy>) {
1191+
// Unlike 'private', 'firstprivate' applies to the compute op, not the
1192+
// loop op.
1193+
applyToComputeOp(clause);
1194+
} else {
1195+
llvm_unreachable("Unknown construct kind in VisitFirstPrivateClause");
1196+
}
1197+
}
11581198
};
11591199

11601200
template <typename OpTy>

0 commit comments

Comments
 (0)