@@ -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+
25922649std::pair<VarDecl *, VarDecl *>
25932650SemaOpenACC::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