Skip to content

Commit 8513699

Browse files
authored
[OpenACC] 'reduction' 'one-init' lowering, */&& operators. (llvm#156122)
The * and && operators of a reduction require a starting value of '1'. This patch implements that by looping through every type and creating an init-list that puts a 1 in place of every initializer. This patch will be followed up by a patch that generalizes this, as `min`, `max`, and `&` all have different initial values.
1 parent cb80fa7 commit 8513699

19 files changed

+1900
-164
lines changed

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 83 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2589,6 +2589,63 @@ SemaOpenACC::ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
25892589
return BuildOpenACCAsteriskSizeExpr(AsteriskLoc);
25902590
}
25912591

2592+
/// Loops through a type and generates an appropriate InitListExpr to generate
2593+
/// type initialization.
2594+
static Expr *GenerateReductionInitRecipeExpr(ASTContext &Context,
2595+
SourceRange ExprRange,
2596+
QualType Ty) {
2597+
Ty = Ty.getCanonicalType();
2598+
llvm::SmallVector<Expr *> Exprs;
2599+
2600+
if (const RecordDecl *RD = Ty->getAsRecordDecl()) {
2601+
for (auto *F : RD->fields()) {
2602+
if (Expr *NewExpr =
2603+
GenerateReductionInitRecipeExpr(Context, ExprRange, F->getType()))
2604+
Exprs.push_back(NewExpr);
2605+
else
2606+
return nullptr;
2607+
}
2608+
} else if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) {
2609+
for (uint64_t Idx = 0; Idx < AT->getZExtSize(); ++Idx) {
2610+
if (Expr *NewExpr = GenerateReductionInitRecipeExpr(Context, ExprRange,
2611+
AT->getElementType()))
2612+
Exprs.push_back(NewExpr);
2613+
else
2614+
return nullptr;
2615+
}
2616+
2617+
} else if (Ty->isPointerType()) {
2618+
// For now, we are going to punt/not initialize pointer types, as
2619+
// discussions/designs are ongoing on how to express this behavior,
2620+
// particularly since they probably need the 'bounds' passed to them
2621+
// correctly. A future patch/patch set will go through all of the pointer
2622+
// values for all of the recipes to make sure we have a sane behavior.
2623+
2624+
// For now, this will result in a NYI during code generation for
2625+
// no-initializer.
2626+
return nullptr;
2627+
} else {
2628+
assert(Ty->isScalarType());
2629+
2630+
// TODO: OpenACC: This currently only works for '1', but we need to figure
2631+
// out a way to do least/largest/all-1s.
2632+
if (Ty->isFloatingType()) {
2633+
Exprs.push_back(FloatingLiteral::Create(
2634+
Context, llvm::APFloat::getOne(Context.getFloatTypeSemantics(Ty)),
2635+
/*isExact=*/true, Ty, ExprRange.getBegin()));
2636+
} else {
2637+
Exprs.push_back(IntegerLiteral::Create(
2638+
Context, llvm::APInt(Context.getTypeSize(Ty), 1), Ty,
2639+
ExprRange.getBegin()));
2640+
}
2641+
}
2642+
2643+
Expr *InitExpr = new (Context)
2644+
InitListExpr(Context, ExprRange.getBegin(), Exprs, ExprRange.getEnd());
2645+
InitExpr->setType(Ty);
2646+
return InitExpr;
2647+
}
2648+
25922649
std::pair<VarDecl *, VarDecl *>
25932650
SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK,
25942651
OpenACCReductionOperator ReductionOperator,
@@ -2637,13 +2694,24 @@ SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK,
26372694
Sema::TentativeAnalysisScope Trap{SemaRef};
26382695
InitializedEntity Entity = InitializedEntity::InitializeVariable(Recipe);
26392696

2697+
auto FinishValueInit = [&](Expr *InitExpr) {
2698+
if (InitExpr) {
2699+
InitializationKind Kind = InitializationKind::CreateForInit(
2700+
Recipe->getLocation(), /*DirectInit=*/true, InitExpr);
2701+
InitializationSequence InitSeq(SemaRef.SemaRef, Entity, Kind, InitExpr,
2702+
/*TopLevelOfInitList=*/false,
2703+
/*TreatUnavailableAsInvalid=*/false);
2704+
return InitSeq.Perform(SemaRef.SemaRef, Entity, Kind, InitExpr, &VarTy);
2705+
}
2706+
return ExprEmpty();
2707+
};
2708+
26402709
if (CK == OpenACCClauseKind::Private) {
26412710
InitializationKind Kind =
26422711
InitializationKind::CreateDefault(Recipe->getLocation());
26432712

26442713
InitializationSequence InitSeq(SemaRef.SemaRef, Entity, Kind, {});
26452714
Init = InitSeq.Perform(SemaRef.SemaRef, Entity, Kind, {});
2646-
26472715
} else if (CK == OpenACCClauseKind::FirstPrivate) {
26482716
// Create a VarDecl to be the 'copied-from' for the copy section of the
26492717
// recipe. This allows us to make the association so that we can use the
@@ -2717,12 +2785,7 @@ SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK,
27172785
InitExpr = TemporaryDRE;
27182786
}
27192787

2720-
InitializationKind Kind = InitializationKind::CreateForInit(
2721-
Recipe->getLocation(), /*DirectInit=*/true, InitExpr);
2722-
InitializationSequence InitSeq(SemaRef.SemaRef, Entity, Kind, InitExpr,
2723-
/*TopLevelOfInitList=*/false,
2724-
/*TreatUnavailableAsInvalid=*/false);
2725-
Init = InitSeq.Perform(SemaRef.SemaRef, Entity, Kind, InitExpr, &VarTy);
2788+
Init = FinishValueInit(InitExpr);
27262789
} else if (CK == OpenACCClauseKind::Reduction) {
27272790
// How we initialize the reduction variable depends on the operator used,
27282791
// according to the chart in OpenACC 3.3 section 2.6.15.
@@ -2733,14 +2796,24 @@ SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK,
27332796
// are used for code generation, we can just ignore/not bother doing any
27342797
// initialization here.
27352798
break;
2736-
case OpenACCReductionOperator::Multiplication:
27372799
case OpenACCReductionOperator::Max:
27382800
case OpenACCReductionOperator::Min:
27392801
case OpenACCReductionOperator::BitwiseAnd:
2740-
case OpenACCReductionOperator::And:
27412802
// TODO: OpenACC: figure out init for these.
27422803
break;
27432804

2805+
case OpenACCReductionOperator::Multiplication:
2806+
case OpenACCReductionOperator::And: {
2807+
// '&&' initializes every field to 1. However, we need to loop through
2808+
// every field/element and generate an initializer for each of the
2809+
// elements.
2810+
2811+
Expr *InitExpr = GenerateReductionInitRecipeExpr(
2812+
getASTContext(), VarExpr->getSourceRange(), VarTy);
2813+
2814+
Init = FinishValueInit(InitExpr);
2815+
break;
2816+
}
27442817
case OpenACCReductionOperator::Addition:
27452818
case OpenACCReductionOperator::BitwiseOr:
27462819
case OpenACCReductionOperator::BitwiseXOr:
@@ -2754,12 +2827,7 @@ SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK,
27542827
// will get this type correct/etc.
27552828
InitExpr->setType(getASTContext().VoidTy);
27562829

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);
2830+
Init = FinishValueInit(InitExpr);
27632831
break;
27642832
}
27652833
}

0 commit comments

Comments
 (0)