Skip to content

Commit 4845b3e

Browse files
authored
[OpenACC][CIR] Impl reduction recipe pointer/array bound lowering (#161726)
Just like with private, the lowering for these bounds are all pretty trivial. This patch enables them for reduction, which has everything in common except the init pattern, but that is handled/managed by Sema. This also adds sufficient testing to spot-check the allocation/initialization/destruction/etc.
1 parent 3c5c82d commit 4845b3e

23 files changed

+9118
-95
lines changed

clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -427,22 +427,20 @@ void OpenACCRecipeBuilderBase::makeBoundsInit(
427427
cgf.emitAutoVarInit(tempDeclEmission);
428428
}
429429

430-
// TODO: OpenACC: When we get this implemented for the reduction/firstprivate,
431-
// this might end up re-merging with createRecipeInitCopy. For now, keep it
432-
// separate until we're sure what everything looks like to keep this as clean
433-
// as possible.
434-
void OpenACCRecipeBuilderBase::createPrivateInitRecipe(
430+
// TODO: OpenACC: when we start doing firstprivate for array/vlas/etc, we
431+
// probably need to do a little work about the 'init' calls to put it in 'copy'
432+
// region instead.
433+
void OpenACCRecipeBuilderBase::createInitRecipe(
435434
mlir::Location loc, mlir::Location locEnd, SourceRange exprRange,
436-
mlir::Value mainOp, mlir::acc::PrivateRecipeOp recipe, size_t numBounds,
435+
mlir::Value mainOp, mlir::Region &recipeInitRegion, size_t numBounds,
437436
llvm::ArrayRef<QualType> boundTypes, const VarDecl *allocaDecl,
438437
QualType origType) {
439438
assert(allocaDecl && "Required recipe variable not set?");
440439
CIRGenFunction::DeclMapRevertingRAII declMapRAII{cgf, allocaDecl};
441440

442-
mlir::Block *block =
443-
createRecipeBlock(recipe.getInitRegion(), mainOp.getType(), loc,
444-
numBounds, /*isInit=*/true);
445-
builder.setInsertionPointToEnd(&recipe.getInitRegion().back());
441+
mlir::Block *block = createRecipeBlock(recipeInitRegion, mainOp.getType(),
442+
loc, numBounds, /*isInit=*/true);
443+
builder.setInsertionPointToEnd(&recipeInitRegion.back());
446444
CIRGenFunction::LexicalScope ls(cgf, loc, block);
447445

448446
const Type *allocaPointeeType =
@@ -458,7 +456,7 @@ void OpenACCRecipeBuilderBase::createPrivateInitRecipe(
458456
// Sema::TentativeAnalysisScopes in SemaOpenACC::CreateInitRecipe, it'll
459457
// emit an error to tell us. However, emitting those errors during
460458
// production is a violation of the standard, so we cannot do them.
461-
cgf.cgm.errorNYI(exprRange, "private default-init recipe");
459+
cgf.cgm.errorNYI(exprRange, "private/reduction default-init recipe");
462460
}
463461

464462
if (!numBounds) {
@@ -469,7 +467,7 @@ void OpenACCRecipeBuilderBase::createPrivateInitRecipe(
469467
cgf.emitAutoVarInit(tempDeclEmission);
470468
} else {
471469
mlir::Value alloca = makeBoundsAlloca(
472-
block, exprRange, loc, "openacc.private.init", numBounds, boundTypes);
470+
block, exprRange, loc, allocaDecl->getName(), numBounds, boundTypes);
473471

474472
// If the initializer is trivial, there is nothing to do here, so save
475473
// ourselves some effort.
@@ -521,10 +519,10 @@ void OpenACCRecipeBuilderBase::createFirstprivateRecipeCopy(
521519
// doesn't restore it aftewards.
522520
void OpenACCRecipeBuilderBase::createReductionRecipeCombiner(
523521
mlir::Location loc, mlir::Location locEnd, mlir::Value mainOp,
524-
mlir::acc::ReductionRecipeOp recipe) {
525-
mlir::Block *block = builder.createBlock(
526-
&recipe.getCombinerRegion(), recipe.getCombinerRegion().end(),
527-
{mainOp.getType(), mainOp.getType()}, {loc, loc});
522+
mlir::acc::ReductionRecipeOp recipe, size_t numBounds) {
523+
mlir::Block *block =
524+
createRecipeBlock(recipe.getCombinerRegion(), mainOp.getType(), loc,
525+
numBounds, /*isInit=*/false);
528526
builder.setInsertionPointToEnd(&recipe.getCombinerRegion().back());
529527
CIRGenFunction::LexicalScope ls(cgf, loc, block);
530528

clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.h

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ class OpenACCRecipeBuilderBase {
6464
// doesn't restore it aftewards.
6565
void createReductionRecipeCombiner(mlir::Location loc, mlir::Location locEnd,
6666
mlir::Value mainOp,
67-
mlir::acc::ReductionRecipeOp recipe);
68-
void createPrivateInitRecipe(mlir::Location loc, mlir::Location locEnd,
69-
SourceRange exprRange, mlir::Value mainOp,
70-
mlir::acc::PrivateRecipeOp recipe,
71-
size_t numBounds,
72-
llvm::ArrayRef<QualType> boundTypes,
73-
const VarDecl *allocaDecl, QualType origType);
67+
mlir::acc::ReductionRecipeOp recipe,
68+
size_t numBounds);
69+
void createInitRecipe(mlir::Location loc, mlir::Location locEnd,
70+
SourceRange exprRange, mlir::Value mainOp,
71+
mlir::Region &recipeInitRegion, size_t numBounds,
72+
llvm::ArrayRef<QualType> boundTypes,
73+
const VarDecl *allocaDecl, QualType origType);
7474

7575
void createRecipeDestroySection(mlir::Location loc, mlir::Location locEnd,
7676
mlir::Value mainOp, CharUnits alignment,
@@ -224,10 +224,10 @@ class OpenACCRecipeBuilder : OpenACCRecipeBuilderBase {
224224
// TODO: OpenACC: This is a bit of a hackery to get this to not change for
225225
// the non-private recipes. This will be removed soon, when we get this
226226
// 'right' for firstprivate and reduction.
227-
if constexpr (!std::is_same_v<RecipeTy, mlir::acc::PrivateRecipeOp>) {
227+
if constexpr (std::is_same_v<RecipeTy, mlir::acc::FirstprivateRecipeOp>) {
228228
if (numBounds) {
229229
cgf.cgm.errorNYI(varRef->getSourceRange(),
230-
"firstprivate/reduction-init with bounds");
230+
"firstprivate-init with bounds");
231231
}
232232
boundTypes = {};
233233
numBounds = 0;
@@ -260,18 +260,25 @@ class OpenACCRecipeBuilder : OpenACCRecipeBuilderBase {
260260
insertLocation = modBuilder.saveInsertionPoint();
261261

262262
if constexpr (std::is_same_v<RecipeTy, mlir::acc::PrivateRecipeOp>) {
263-
createPrivateInitRecipe(loc, locEnd, varRef->getSourceRange(), mainOp,
264-
recipe, numBounds, boundTypes, varRecipe,
265-
origType);
263+
createInitRecipe(loc, locEnd, varRef->getSourceRange(), mainOp,
264+
recipe.getInitRegion(), numBounds, boundTypes, varRecipe,
265+
origType);
266+
} else if constexpr (std::is_same_v<RecipeTy,
267+
mlir::acc::ReductionRecipeOp>) {
268+
createInitRecipe(loc, locEnd, varRef->getSourceRange(), mainOp,
269+
recipe.getInitRegion(), numBounds, boundTypes, varRecipe,
270+
origType);
271+
createReductionRecipeCombiner(loc, locEnd, mainOp, recipe, numBounds);
266272
} else {
273+
static_assert(std::is_same_v<RecipeTy, mlir::acc::FirstprivateRecipeOp>);
274+
// TODO: OpenACC: we probably want this to call createInitRecipe as well,
275+
// but do so in a way that omits the 'initialization', so that we can do
276+
// it separately, since it belongs in the 'copy' region. It also might
277+
// need a way of getting the tempDeclEmission out of it for that purpose.
267278
createRecipeInitCopy(loc, locEnd, varRef->getSourceRange(), mainOp,
268279
recipe, varRecipe, temporary);
269280
}
270281

271-
if constexpr (std::is_same_v<RecipeTy, mlir::acc::ReductionRecipeOp>) {
272-
createReductionRecipeCombiner(loc, locEnd, mainOp, recipe);
273-
}
274-
275282
if (origType.isDestructedType())
276283
createRecipeDestroySection(
277284
loc, locEnd, mainOp, cgf.getContext().getDeclAlign(varRecipe),

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2894,17 +2894,18 @@ SemaOpenACC::CreateFirstPrivateInitRecipe(const Expr *VarExpr) {
28942894

28952895
OpenACCReductionRecipe SemaOpenACC::CreateReductionInitRecipe(
28962896
OpenACCReductionOperator ReductionOperator, const Expr *VarExpr) {
2897-
// TODO: OpenACC: This shouldn't be necessary, see PrivateInitRecipe
2898-
VarExpr = StripOffBounds(VarExpr);
2899-
2897+
// We don't strip bounds here, so that we are doing our recipe init at the
2898+
// 'lowest' possible level. Codegen is going to have to do its own 'looping'.
29002899
if (!VarExpr || VarExpr->getType()->isDependentType())
29012900
return OpenACCReductionRecipe::Empty();
29022901

29032902
QualType VarTy =
29042903
VarExpr->getType().getNonReferenceType().getUnqualifiedType();
29052904

2906-
// TODO: OpenACC: for arrays/bounds versions, we're going to have to do a
2907-
// different initializer, but for now we can go ahead with this.
2905+
// Array sections are special, and we have to treat them that way.
2906+
if (const auto *ASE =
2907+
dyn_cast<ArraySectionExpr>(VarExpr->IgnoreParenImpCasts()))
2908+
VarTy = ArraySectionExpr::getBaseOriginalType(ASE);
29082909

29092910
VarDecl *AllocaDecl = CreateAllocaDecl(
29102911
getASTContext(), SemaRef.getCurContext(), VarExpr->getBeginLoc(),

0 commit comments

Comments
 (0)