Skip to content

Commit bef7c1b

Browse files
authored
[OpenACC] 'reduction' init lowering for +, |, ^, || (#155924)
These four operators have an initial value of 0, so they are able to use C/C++ 'zero init'. This patch adds the infrastructure to the Sema init calculations to differentiate based on the reduction operator, then enables emission of the inits in CodeGen (which should work for all inits, once generated). The rest of this test is just updating validation to make sure that the inits happen correctly for all 4 operators.
1 parent df4c367 commit bef7c1b

23 files changed

+2349
-329
lines changed

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,14 @@ class SemaOpenACC : public SemaBase {
244244
// 'temporary' created for the init (in the case of a copy), such as with
245245
// firstprivate.
246246
std::pair<VarDecl *, VarDecl *> CreateInitRecipe(OpenACCClauseKind CK,
247-
const Expr *VarExpr);
247+
const Expr *VarExpr) {
248+
assert(CK != OpenACCClauseKind::Reduction);
249+
return CreateInitRecipe(CK, OpenACCReductionOperator::Invalid, VarExpr);
250+
}
251+
std::pair<VarDecl *, VarDecl *>
252+
CreateInitRecipe(OpenACCClauseKind CK,
253+
OpenACCReductionOperator ReductionOperator,
254+
const Expr *VarExpr);
248255

249256
public:
250257
ComputeConstructInfo &getActiveComputeConstructInfo() {

clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ class OpenACCClauseCIREmitter final
425425
&recipe.getCopyRegion(), recipe.getCopyRegion().end(),
426426
{mainOp.getType(), mainOp.getType()}, {loc, loc});
427427
builder.setInsertionPointToEnd(&recipe.getCopyRegion().back());
428+
CIRGenFunction::LexicalScope ls(cgf, loc, block);
428429

429430
mlir::BlockArgument fromArg = block->getArgument(0);
430431
mlir::BlockArgument toArg = block->getArgument(1);
@@ -457,21 +458,19 @@ class OpenACCClauseCIREmitter final
457458
RecipeTy recipe, const VarDecl *varRecipe,
458459
const VarDecl *temporary) {
459460
assert(varRecipe && "Required recipe variable not set?");
460-
if constexpr (std::is_same_v<RecipeTy, mlir::acc::ReductionRecipeOp>) {
461-
// We haven't implemented the 'init' recipe for Reduction yet, so NYI
462-
// it.
463-
cgf.cgm.errorNYI(exprRange, "OpenACC Reduction recipe init");
464-
}
465461

466462
CIRGenFunction::AutoVarEmission tempDeclEmission{
467463
CIRGenFunction::AutoVarEmission::invalid()};
468464
CIRGenFunction::DeclMapRevertingRAII declMapRAII{cgf, varRecipe};
469465

470466
// Do the 'init' section of the recipe IR, which does an alloca, then the
471467
// initialization (except for firstprivate).
472-
builder.createBlock(&recipe.getInitRegion(), recipe.getInitRegion().end(),
473-
{mainOp.getType()}, {loc});
468+
mlir::Block *block = builder.createBlock(&recipe.getInitRegion(),
469+
recipe.getInitRegion().end(),
470+
{mainOp.getType()}, {loc});
474471
builder.setInsertionPointToEnd(&recipe.getInitRegion().back());
472+
CIRGenFunction::LexicalScope ls(cgf, loc, block);
473+
475474
tempDeclEmission =
476475
cgf.emitAutoVarAlloca(*varRecipe, builder.saveInsertionPoint());
477476

@@ -496,6 +495,13 @@ class OpenACCClauseCIREmitter final
496495
cgf.cgm.errorNYI(exprRange, "private default-init recipe");
497496
}
498497
cgf.emitAutoVarInit(tempDeclEmission);
498+
} else if constexpr (std::is_same_v<RecipeTy,
499+
mlir::acc::ReductionRecipeOp>) {
500+
// Unlike Private, the recipe here is always required as it has to do
501+
// init, not just 'default' init.
502+
if (!varRecipe->getInit())
503+
cgf.cgm.errorNYI(exprRange, "reduction init recipe");
504+
cgf.emitAutoVarInit(tempDeclEmission);
499505
}
500506

501507
mlir::acc::YieldOp::create(builder, locEnd);
@@ -527,6 +533,7 @@ class OpenACCClauseCIREmitter final
527533
&recipe.getCombinerRegion(), recipe.getCombinerRegion().end(),
528534
{mainOp.getType(), mainOp.getType()}, {loc, loc});
529535
builder.setInsertionPointToEnd(&recipe.getCombinerRegion().back());
536+
CIRGenFunction::LexicalScope ls(cgf, loc, block);
530537

531538
mlir::BlockArgument lhsArg = block->getArgument(0);
532539

@@ -544,6 +551,7 @@ class OpenACCClauseCIREmitter final
544551
mlir::Block *block = builder.createBlock(
545552
&destroyRegion, destroyRegion.end(), {mainOp.getType()}, {loc});
546553
builder.setInsertionPointToEnd(&destroyRegion.back());
554+
CIRGenFunction::LexicalScope ls(cgf, loc, block);
547555

548556
mlir::Type elementTy =
549557
mlir::cast<cir::PointerType>(mainOp.getType()).getPointee();

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2590,7 +2590,9 @@ SemaOpenACC::ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
25902590
}
25912591

25922592
std::pair<VarDecl *, VarDecl *>
2593-
SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK, const Expr *VarExpr) {
2593+
SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK,
2594+
OpenACCReductionOperator ReductionOperator,
2595+
const Expr *VarExpr) {
25942596
// Strip off any array subscripts/array section exprs to get to the type of
25952597
// the variable.
25962598
while (isa_and_present<ArraySectionExpr, ArraySubscriptExpr>(VarExpr)) {
@@ -2722,7 +2724,45 @@ SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK, const Expr *VarExpr) {
27222724
/*TreatUnavailableAsInvalid=*/false);
27232725
Init = InitSeq.Perform(SemaRef.SemaRef, Entity, Kind, InitExpr, &VarTy);
27242726
} else if (CK == OpenACCClauseKind::Reduction) {
2725-
// TODO: OpenACC: Implement this for whatever reduction needs.
2727+
// How we initialize the reduction variable depends on the operator used,
2728+
// according to the chart in OpenACC 3.3 section 2.6.15.
2729+
2730+
switch (ReductionOperator) {
2731+
case OpenACCReductionOperator::Invalid:
2732+
// This can only happen when there is an error, and since these inits
2733+
// are used for code generation, we can just ignore/not bother doing any
2734+
// initialization here.
2735+
break;
2736+
case OpenACCReductionOperator::Multiplication:
2737+
case OpenACCReductionOperator::Max:
2738+
case OpenACCReductionOperator::Min:
2739+
case OpenACCReductionOperator::BitwiseAnd:
2740+
case OpenACCReductionOperator::And:
2741+
// TODO: OpenACC: figure out init for these.
2742+
break;
2743+
2744+
case OpenACCReductionOperator::Addition:
2745+
case OpenACCReductionOperator::BitwiseOr:
2746+
case OpenACCReductionOperator::BitwiseXOr:
2747+
case OpenACCReductionOperator::Or: {
2748+
// +, |, ^, and || all use 0 for their initializers, so we can just
2749+
// use 'zero init' here and not bother with the rest of the
2750+
// array/compound type/etc contents.
2751+
Expr *InitExpr = new (getASTContext()) InitListExpr(
2752+
getASTContext(), VarExpr->getBeginLoc(), {}, VarExpr->getEndLoc());
2753+
// we set this to void so that the initialization sequence generation
2754+
// will get this type correct/etc.
2755+
InitExpr->setType(getASTContext().VoidTy);
2756+
2757+
InitializationKind Kind = InitializationKind::CreateForInit(
2758+
Recipe->getLocation(), /*DirectInit=*/true, InitExpr);
2759+
InitializationSequence InitSeq(SemaRef.SemaRef, Entity, Kind, InitExpr,
2760+
/*TopLevelOfInitList=*/false,
2761+
/*TreatUnavailableAsInvalid=*/false);
2762+
Init = InitSeq.Perform(SemaRef.SemaRef, Entity, Kind, InitExpr, &VarTy);
2763+
break;
2764+
}
2765+
}
27262766
} else {
27272767
llvm_unreachable("Unknown clause kind in CreateInitRecipe");
27282768
}

clang/lib/Sema/SemaOpenACCClause.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,9 +1784,10 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause(
17841784
ValidVars.push_back(Res.get());
17851785

17861786
VarDecl *InitRecipe =
1787-
SemaRef.CreateInitRecipe(OpenACCClauseKind::Reduction, Res.get())
1787+
SemaRef
1788+
.CreateInitRecipe(OpenACCClauseKind::Reduction,
1789+
Clause.getReductionOp(), Res.get())
17881790
.first;
1789-
// TODO: OpenACC: Create the reduction operation recipe here too.
17901791
Recipes.push_back({InitRecipe});
17911792
}
17921793
}

clang/lib/Sema/TreeTransform.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12430,11 +12430,11 @@ void OpenACCClauseTransform<Derived>::VisitReductionClause(
1243012430
if (OrigRecipes.RecipeDecl)
1243112431
InitRecipe = OrigRecipes.RecipeDecl;
1243212432
else
12433-
InitRecipe =
12434-
Self.getSema()
12435-
.OpenACC()
12436-
.CreateInitRecipe(OpenACCClauseKind::Reduction, Res.get())
12437-
.first;
12433+
InitRecipe = Self.getSema()
12434+
.OpenACC()
12435+
.CreateInitRecipe(OpenACCClauseKind::Reduction,
12436+
C.getReductionOp(), Res.get())
12437+
.first;
1243812438

1243912439
Recipes.push_back({InitRecipe});
1244012440
}

0 commit comments

Comments
 (0)