diff options
Diffstat (limited to 'clang/lib/Sema/SemaOpenACC.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOpenACC.cpp | 169 |
1 files changed, 1 insertions, 168 deletions
diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index 779b6e9..f3969a9 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -2898,15 +2898,6 @@ OpenACCReductionRecipe SemaOpenACC::CreateReductionInitRecipe( dyn_cast<ArraySectionExpr>(VarExpr->IgnoreParenImpCasts())) VarTy = ASE->getElementType(); - llvm::SmallVector<OpenACCReductionRecipe::CombinerRecipe, 1> CombinerRecipes; - - // We use the 'set-ness' of the alloca-decl to determine whether the combiner - // is 'set' or not, so we can skip any attempts at it if we're going to fail - // at any of the combiners. - if (CreateReductionCombinerRecipe(VarExpr->getBeginLoc(), ReductionOperator, - VarTy, CombinerRecipes)) - return OpenACCReductionRecipe::Empty(); - VarDecl *AllocaDecl = CreateAllocaDecl( getASTContext(), SemaRef.getCurContext(), VarExpr->getBeginLoc(), &getASTContext().Idents.get("openacc.reduction.init"), VarTy); @@ -2955,163 +2946,5 @@ OpenACCReductionRecipe SemaOpenACC::CreateReductionInitRecipe( AllocaDecl->setInit(Init.get()); AllocaDecl->setInitStyle(VarDecl::CallInit); } - - return OpenACCReductionRecipe(AllocaDecl, CombinerRecipes); -} - -bool SemaOpenACC::CreateReductionCombinerRecipe( - SourceLocation Loc, OpenACCReductionOperator ReductionOperator, - QualType VarTy, - llvm::SmallVectorImpl<OpenACCReductionRecipe::CombinerRecipe> - &CombinerRecipes) { - // Now we can try to generate the 'combiner' recipe. This is a little - // complicated in that if the 'VarTy' is an array type, we want to take its - // element type so we can generate that. Additionally, if this is a struct, - // we have two options: If there is overloaded operators, we want to take - // THOSE, else we want to do the individual elements. - - BinaryOperatorKind BinOp; - switch (ReductionOperator) { - case OpenACCReductionOperator::Invalid: - // This can only happen when there is an error, and since these inits - // are used for code generation, we can just ignore/not bother doing any - // initialization here. - CombinerRecipes.push_back({nullptr, nullptr, nullptr}); - return false; - case OpenACCReductionOperator::Addition: - BinOp = BinaryOperatorKind::BO_AddAssign; - break; - case OpenACCReductionOperator::Multiplication: - BinOp = BinaryOperatorKind::BO_MulAssign; - break; - case OpenACCReductionOperator::BitwiseAnd: - BinOp = BinaryOperatorKind::BO_AndAssign; - break; - case OpenACCReductionOperator::BitwiseOr: - BinOp = BinaryOperatorKind::BO_OrAssign; - break; - case OpenACCReductionOperator::BitwiseXOr: - BinOp = BinaryOperatorKind::BO_XorAssign; - break; - - case OpenACCReductionOperator::Max: - case OpenACCReductionOperator::Min: - case OpenACCReductionOperator::And: - case OpenACCReductionOperator::Or: - // We just want a 'NYI' error in the backend, so leave an empty combiner - // recipe, and claim success. - CombinerRecipes.push_back({nullptr, nullptr, nullptr}); - return false; - } - - // If VarTy is an array type, at the top level only, we want to do our - // compares/decomp/etc at the element level. - if (auto *AT = getASTContext().getAsArrayType(VarTy)) - VarTy = AT->getElementType(); - - assert(!VarTy->isArrayType() && "Only 1 level of array allowed"); - - auto tryCombiner = [&, this](DeclRefExpr *LHSDRE, DeclRefExpr *RHSDRE, - bool IncludeTrap) { - // TODO: OpenACC: we have to figure out based on the bin-op how to do the - // ones that we can't just use compound operators for. So &&, ||, max, and - // min aren't really clear what we could do here. - if (IncludeTrap) { - // Trap all of the errors here, we'll emit our own at the end. - Sema::TentativeAnalysisScope Trap{SemaRef}; - - return SemaRef.BuildBinOp(SemaRef.getCurScope(), Loc, BinOp, LHSDRE, - RHSDRE, - /*ForFoldExpr=*/false); - } else { - return SemaRef.BuildBinOp(SemaRef.getCurScope(), Loc, BinOp, LHSDRE, - RHSDRE, - /*ForFoldExpr=*/false); - } - }; - - struct CombinerAttemptTy { - VarDecl *LHS; - DeclRefExpr *LHSDRE; - VarDecl *RHS; - DeclRefExpr *RHSDRE; - Expr *Op; - }; - - auto formCombiner = [&, this](QualType Ty) -> CombinerAttemptTy { - VarDecl *LHSDecl = CreateAllocaDecl( - getASTContext(), SemaRef.getCurContext(), Loc, - &getASTContext().Idents.get("openacc.reduction.combiner.lhs"), Ty); - auto *LHSDRE = DeclRefExpr::Create( - getASTContext(), NestedNameSpecifierLoc{}, SourceLocation{}, LHSDecl, - /*ReferstoEnclosingVariableOrCapture=*/false, - DeclarationNameInfo{DeclarationName{LHSDecl->getDeclName()}, - LHSDecl->getBeginLoc()}, - Ty, clang::VK_LValue, LHSDecl, nullptr, NOUR_None); - VarDecl *RHSDecl = CreateAllocaDecl( - getASTContext(), SemaRef.getCurContext(), Loc, - &getASTContext().Idents.get("openacc.reduction.combiner.lhs"), Ty); - auto *RHSDRE = DeclRefExpr::Create( - getASTContext(), NestedNameSpecifierLoc{}, SourceLocation{}, RHSDecl, - /*ReferstoEnclosingVariableOrCapture=*/false, - DeclarationNameInfo{DeclarationName{RHSDecl->getDeclName()}, - RHSDecl->getBeginLoc()}, - Ty, clang::VK_LValue, RHSDecl, nullptr, NOUR_None); - - ExprResult BinOpResult = tryCombiner(LHSDRE, RHSDRE, /*IncludeTrap=*/true); - - return {LHSDecl, LHSDRE, RHSDecl, RHSDRE, BinOpResult.get()}; - }; - - CombinerAttemptTy TopLevelCombinerInfo = formCombiner(VarTy); - - if (TopLevelCombinerInfo.Op) { - if (!TopLevelCombinerInfo.Op->containsErrors() && - TopLevelCombinerInfo.Op->isInstantiationDependent()) { - // If this is instantiation dependent, we're just going to 'give up' here - // and count on us to get it right during instantaition. - CombinerRecipes.push_back({nullptr, nullptr, nullptr}); - return false; - } else if (!TopLevelCombinerInfo.Op->containsErrors()) { - // Else, we succeeded, we can just return this combiner. - CombinerRecipes.push_back({TopLevelCombinerInfo.LHS, - TopLevelCombinerInfo.RHS, - TopLevelCombinerInfo.Op}); - return false; - } - } - - // Since the 'root' level didn't fail, the only thing that could be successful - // is a struct that we decompose on its individual fields. - - RecordDecl *RD = VarTy->getAsRecordDecl(); - if (!RD) { - Diag(Loc, diag::err_acc_reduction_recipe_no_op) << VarTy; - tryCombiner(TopLevelCombinerInfo.LHSDRE, TopLevelCombinerInfo.RHSDRE, - /*IncludeTrap=*/false); - return true; - } - - for (const FieldDecl *FD : RD->fields()) { - CombinerAttemptTy FieldCombinerInfo = formCombiner(FD->getType()); - - if (!FieldCombinerInfo.Op || FieldCombinerInfo.Op->containsErrors()) { - Diag(Loc, diag::err_acc_reduction_recipe_no_op) << FD->getType(); - Diag(FD->getBeginLoc(), diag::note_acc_reduction_recipe_noop_field) << RD; - tryCombiner(FieldCombinerInfo.LHSDRE, FieldCombinerInfo.RHSDRE, - /*IncludeTrap=*/false); - return true; - } - - if (FieldCombinerInfo.Op->isInstantiationDependent()) { - // If this is instantiation dependent, we're just going to 'give up' here - // and count on us to get it right during instantaition. - CombinerRecipes.push_back({nullptr, nullptr, nullptr}); - } else { - CombinerRecipes.push_back( - {FieldCombinerInfo.LHS, FieldCombinerInfo.RHS, FieldCombinerInfo.Op}); - } - } - - return false; + return OpenACCReductionRecipe(AllocaDecl, {}); } |