diff options
| author | Alexey Bataev <a.bataev@hotmail.com> | 2016-03-03 03:52:24 +0000 |
|---|---|---|
| committer | Alexey Bataev <a.bataev@hotmail.com> | 2016-03-03 03:52:24 +0000 |
| commit | 2bbf7217eab497204acb7e6671b737d485c25547 (patch) | |
| tree | f0ad8f9c3f3e1aebeada6a5646b674d45469dcd7 /clang/lib | |
| parent | 600ca6fd39fe326130e97314775f8a560b098215 (diff) | |
| download | bcm5719-llvm-2bbf7217eab497204acb7e6671b737d485c25547.tar.gz bcm5719-llvm-2bbf7217eab497204acb7e6671b737d485c25547.zip | |
[OPENMP 4.5] Initial support for data members in 'linear' clause.
OpenMP 4.5 allows to privatize data members of current class in member
functions. Patch adds initial support for privatization of data members
in 'linear' clause, no codegen support.
llvm-svn: 262578
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 12 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 115 |
2 files changed, 58 insertions, 69 deletions
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 90d6a829e14..ddceb1b559c 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -18,6 +18,7 @@ #include "TargetInfo.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtOpenMP.h" +#include "clang/AST/DeclOpenMP.h" using namespace clang; using namespace CodeGen; @@ -30,8 +31,15 @@ class OMPLexicalScope { for (const auto *C : S.clauses()) { if (auto *CPI = OMPClauseWithPreInit::get(C)) { if (auto *PreInit = cast_or_null<DeclStmt>(CPI->getPreInitStmt())) { - for (const auto *I : PreInit->decls()) - CGF.EmitVarDecl(cast<VarDecl>(*I)); + for (const auto *I : PreInit->decls()) { + if (!I->hasAttr<OMPCaptureNoInitAttr>()) + CGF.EmitVarDecl(cast<VarDecl>(*I)); + else { + CodeGenFunction::AutoVarEmission Emission = + CGF.EmitAutoVarAlloca(cast<VarDecl>(*I)); + CGF.EmitAutoVarCleanups(Emission); + } + } } } } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 86ad66f4a62..50148b5187c 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -1706,6 +1706,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, Expr *CaptureExpr, bool WithInit) { + assert(CaptureExpr); ASTContext &C = S.getASTContext(); Expr *Init = CaptureExpr->IgnoreImpCasts(); QualType Ty = Init->getType(); @@ -1723,12 +1724,11 @@ static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, WithInit = true; } auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty); + if (!WithInit) + CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange())); S.CurContext->addHiddenDecl(CED); - if (WithInit) - S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false, - /*TypeMayContainAuto=*/true); - else - S.ActOnUninitializedDecl(CED, /*TypeMayContainAuto=*/true); + S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false, + /*TypeMayContainAuto=*/true); return CED; } @@ -7676,7 +7676,7 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, } if (TopDVar.CKind == OMPC_firstprivate || (!IsOpenMPCapturedDecl(D) && - !cast<OMPCapturedExprDecl>(Ref->getDecl())->getInit())) { + Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { ExprResult RefRes = DefaultLvalueConversion(Ref); if (!RefRes.isUsable()) continue; @@ -8277,7 +8277,7 @@ OMPClause *Sema::ActOnOpenMPReductionClause( buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); if (!IsOpenMPCapturedDecl(D)) { ExprCaptures.push_back(Ref->getDecl()); - if (!cast<OMPCapturedExprDecl>(Ref->getDecl())->getInit()) { + if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { ExprResult RefRes = DefaultLvalueConversion(Ref); if (!RefRes.isUsable()) continue; @@ -8340,115 +8340,96 @@ OMPClause *Sema::ActOnOpenMPLinearClause( } for (auto &RefExpr : VarList) { assert(RefExpr && "NULL expr in OpenMP linear clause."); - if (isa<DependentScopeDeclRefExpr>(RefExpr)) { + SourceLocation ELoc; + SourceRange ERange; + Expr *SimpleRefExpr = RefExpr; + auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, + /*AllowArraySection=*/false); + if (Res.second) { // It will be analyzed later. Vars.push_back(RefExpr); Privates.push_back(nullptr); Inits.push_back(nullptr); - continue; } - - // OpenMP [2.14.3.7, linear clause] - // A list item that appears in a linear clause is subject to the private - // clause semantics described in Section 2.14.3.3 on page 159 except as - // noted. In addition, the value of the new list item on each iteration - // of the associated loop(s) corresponds to the value of the original - // list item before entering the construct plus the logical number of - // the iteration times linear-step. - - SourceLocation ELoc = RefExpr->getExprLoc(); - // OpenMP [2.1, C/C++] - // A list item is a variable name. - // OpenMP [2.14.3.3, Restrictions, p.1] - // A variable that is part of another variable (as an array or - // structure element) cannot appear in a private clause. - DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); - if (!DE || !isa<VarDecl>(DE->getDecl())) { - Diag(ELoc, diag::err_omp_expected_var_name_member_expr) - << 0 << RefExpr->getSourceRange(); + ValueDecl *D = Res.first; + if (!D) continue; - } - VarDecl *VD = cast<VarDecl>(DE->getDecl()); + QualType Type = D->getType(); + auto *VD = dyn_cast<VarDecl>(D); // OpenMP [2.14.3.7, linear clause] // A list-item cannot appear in more than one linear clause. // A list-item that appears in a linear clause cannot appear in any // other data-sharing attribute clause. - DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); + DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); if (DVar.RefExpr) { Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) << getOpenMPClauseName(OMPC_linear); - ReportOriginalDSA(*this, DSAStack, VD, DVar); - continue; - } - - QualType QType = VD->getType(); - if (QType->isDependentType() || QType->isInstantiationDependentType()) { - // It will be analyzed later. - Vars.push_back(DE); - Privates.push_back(nullptr); - Inits.push_back(nullptr); + ReportOriginalDSA(*this, DSAStack, D, DVar); continue; } // A variable must not have an incomplete type or a reference type. - if (RequireCompleteType(ELoc, QType, - diag::err_omp_linear_incomplete_type)) { + if (RequireCompleteType(ELoc, Type, + diag::err_omp_linear_incomplete_type)) continue; - } if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && - !QType->isReferenceType()) { + !Type->isReferenceType()) { Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) - << QType << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); + << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); continue; } - QType = QType.getNonReferenceType(); + Type = Type.getNonReferenceType(); // A list item must not be const-qualified. - if (QType.isConstant(Context)) { + if (Type.isConstant(Context)) { Diag(ELoc, diag::err_omp_const_variable) << getOpenMPClauseName(OMPC_linear); bool IsDecl = + !VD || VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; - Diag(VD->getLocation(), + Diag(D->getLocation(), IsDecl ? diag::note_previous_decl : diag::note_defined_here) - << VD; + << D; continue; } // A list item must be of integral or pointer type. - QType = QType.getUnqualifiedType().getCanonicalType(); - const Type *Ty = QType.getTypePtrOrNull(); + Type = Type.getUnqualifiedType().getCanonicalType(); + const auto *Ty = Type.getTypePtrOrNull(); if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && !Ty->isPointerType())) { - Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << QType; + Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; bool IsDecl = + !VD || VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; - Diag(VD->getLocation(), + Diag(D->getLocation(), IsDecl ? diag::note_previous_decl : diag::note_defined_here) - << VD; + << D; continue; } // Build private copy of original var. - auto *Private = buildVarDecl(*this, ELoc, QType, VD->getName(), - VD->hasAttrs() ? &VD->getAttrs() : nullptr); - auto *PrivateRef = buildDeclRefExpr( - *this, Private, DE->getType().getUnqualifiedType(), DE->getExprLoc()); + auto *Private = buildVarDecl(*this, ELoc, Type, D->getName(), + D->hasAttrs() ? &D->getAttrs() : nullptr); + auto *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); // Build var to save initial value. - VarDecl *Init = buildVarDecl(*this, ELoc, QType, ".linear.start"); + VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); Expr *InitExpr; + DeclRefExpr *Ref = nullptr; + if (!VD) + Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); if (LinKind == OMPC_LINEAR_uval) - InitExpr = VD->getInit(); + InitExpr = VD ? VD->getInit() : SimpleRefExpr; else - InitExpr = DE; + InitExpr = VD ? SimpleRefExpr : Ref; AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), - /*DirectInit*/ false, /*TypeMayContainAuto*/ false); - auto InitRef = buildDeclRefExpr( - *this, Init, DE->getType().getUnqualifiedType(), DE->getExprLoc()); - DSAStack->addDSA(VD, DE, OMPC_linear); - Vars.push_back(DE); + /*DirectInit=*/false, /*TypeMayContainAuto=*/false); + auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); + + DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); + Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); Privates.push_back(PrivateRef); Inits.push_back(InitRef); } |

