diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 76c87b1ddae69a4438a4c73da1ccb7288db35cfa..3bc1b4d7d36df4559cc4300b512dcc4fd81ea206 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -7462,6 +7462,10 @@ public: void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc); + /// \brief Start analysis of clauses. + void StartOpenMPClauses(); + /// \brief End analysis of clauses. + void EndOpenMPClauses(); /// \brief Called on end of data sharing attribute block. void EndOpenMPDSABlock(Stmt *CurDirective); diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp index 21b1bcb9d3a9ec9b18421effd30ab10f043da28c..34e075925fd5f965a4094feffec904a99b383a02 100644 --- a/lib/CodeGen/CGStmtOpenMP.cpp +++ b/lib/CodeGen/CGStmtOpenMP.cpp @@ -533,7 +533,16 @@ void CodeGenFunction::EmitOMPInnerLoop( void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) { auto IC = S.counters().begin(); for (auto F : S.finals()) { - if (LocalDeclMap.lookup(cast<DeclRefExpr>((*IC))->getDecl())) { + auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl()); + if (LocalDeclMap.lookup(OrigVD)) { + DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD), + CapturedStmtInfo->lookup(OrigVD) != nullptr, + (*IC)->getType(), VK_LValue, (*IC)->getExprLoc()); + auto *OrigAddr = EmitLValue(&DRE).getAddress(); + OMPPrivateScope VarScope(*this); + VarScope.addPrivate(OrigVD, + [OrigAddr]() -> llvm::Value *{ return OrigAddr; }); + (void)VarScope.Privatize(); EmitIgnoredExpr(F); } ++IC; @@ -541,8 +550,19 @@ void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) { // Emit the final values of the linear variables. for (auto &&I = S.getClausesOfKind(OMPC_linear); I; ++I) { auto *C = cast<OMPLinearClause>(*I); + auto IC = C->varlist_begin(); for (auto F : C->finals()) { + auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl()); + DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD), + CapturedStmtInfo->lookup(OrigVD) != nullptr, + (*IC)->getType(), VK_LValue, (*IC)->getExprLoc()); + auto *OrigAddr = EmitLValue(&DRE).getAddress(); + OMPPrivateScope VarScope(*this); + VarScope.addPrivate(OrigVD, + [OrigAddr]() -> llvm::Value *{ return OrigAddr; }); + (void)VarScope.Privatize(); EmitIgnoredExpr(F); + ++IC; } } } diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp index 143ef704db90a822a17f769d80110f5d06b6907d..187289ee637d07732ced3af1cbfd1bc02ace715e 100644 --- a/lib/Parse/ParseOpenMP.cpp +++ b/lib/Parse/ParseOpenMP.cpp @@ -223,6 +223,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) { ParseScope OMPDirectiveScope(this, ScopeFlags); Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc); + Actions.StartOpenMPClauses(); while (Tok.isNot(tok::annot_pragma_openmp_end)) { OpenMPClauseKind CKind = Tok.isAnnotation() @@ -242,6 +243,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) { if (Tok.is(tok::comma)) ConsumeToken(); } + Actions.EndOpenMPClauses(); // End location of the directive. EndLoc = Tok.getLocation(); // Consume final annot_pragma_openmp_end. diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index d814b135a3cf6a88122c9957ad89dabdc1170527..43211bf9f5846d21b5891109e820b6bb163268cd 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -114,6 +114,9 @@ private: /// \brief Stack of used declaration and their data-sharing attributes. StackTy Stack; + /// \brief true, if check for DSA must be from parent directive, false, if + /// from current directive. + bool FromParent; Sema &SemaRef; typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator; @@ -124,7 +127,10 @@ private: bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter); public: - explicit DSAStackTy(Sema &S) : Stack(1), SemaRef(S) {} + explicit DSAStackTy(Sema &S) : Stack(1), FromParent(false), SemaRef(S) {} + + bool isFromParent() const { return FromParent; } + void setFromParent(bool Flag) { FromParent = Flag; } void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc) { @@ -418,6 +424,28 @@ bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) { return false; } +/// \brief Build a variable declaration for OpenMP loop iteration variable. +static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, + StringRef Name) { + DeclContext *DC = SemaRef.CurContext; + IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); + TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); + VarDecl *Decl = + VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); + Decl->setImplicit(); + return Decl; +} + +static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, + SourceLocation Loc, + bool RefersToCapture = false) { + D->setReferenced(); + D->markUsed(S.Context); + return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), + SourceLocation(), D, RefersToCapture, Loc, Ty, + VK_LValue); +} + DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) { D = D->getCanonicalDecl(); DSAVarData DVar; @@ -428,12 +456,8 @@ DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) { if (D->getTLSKind() != VarDecl::TLS_None || (D->getStorageClass() == SC_Register && D->hasAttr<AsmLabelAttr>() && !D->isLocalVarDecl())) { - addDSA(D, - DeclRefExpr::Create(SemaRef.getASTContext(), - NestedNameSpecifierLoc(), SourceLocation(), D, - /*RefersToEnclosingVariableOrCapture=*/false, - D->getLocation(), - D->getType().getNonReferenceType(), VK_LValue), + addDSA(D, buildDeclRefExpr(SemaRef, D, D->getType().getNonReferenceType(), + D->getLocation()), OMPC_threadprivate); } if (Stack[0].SharingMap.count(D)) { @@ -592,13 +616,15 @@ bool Sema::IsOpenMPCapturedVar(VarDecl *VD) { assert(LangOpts.OpenMP && "OpenMP is not allowed"); VD = VD->getCanonicalDecl(); if (DSAStack->getCurrentDirective() != OMPD_unknown) { - if (DSAStack->isLoopControlVariable(VD)) + if (DSAStack->isLoopControlVariable(VD) || + (VD->hasLocalStorage() && + isParallelOrTaskRegion(DSAStack->getCurrentDirective()))) return true; - auto DVarPrivate = DSAStack->getTopDSA(VD, /*FromParent=*/false); + auto DVarPrivate = DSAStack->getTopDSA(VD, DSAStack->isFromParent()); if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) return true; DVarPrivate = DSAStack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(), - /*FromParent=*/false); + DSAStack->isFromParent()); return DVarPrivate.CKind != OMPC_unknown; } return false; @@ -613,6 +639,14 @@ void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, PushExpressionEvaluationContext(PotentiallyEvaluated); } +void Sema::StartOpenMPClauses() { + DSAStack->setFromParent(/*Flag=*/true); +} + +void Sema::EndOpenMPClauses() { + DSAStack->setFromParent(/*Flag=*/false); +} + void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] // A variable of class type (or array thereof) that appears in a lastprivate @@ -636,18 +670,14 @@ void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { // by the address of the new private variable in CodeGen. This new // variable is not added to IdResolver, so the code in the OpenMP // region uses original variable for proper diagnostics. - auto *VDPrivate = VarDecl::Create( - Context, CurContext, DE->getLocStart(), DE->getExprLoc(), - VD->getIdentifier(), VD->getType(), VD->getTypeSourceInfo(), - SC_Auto); + auto *VDPrivate = + buildVarDecl(*this, DE->getExprLoc(), + VD->getType().getUnqualifiedType(), VD->getName()); ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); if (VDPrivate->isInvalidDecl()) continue; - CurContext->addDecl(VDPrivate); - PrivateCopies.push_back(DeclRefExpr::Create( - Context, NestedNameSpecifierLoc(), SourceLocation(), VDPrivate, - /*RefersToEnclosingVariableOrCapture=*/false, SourceLocation(), - DE->getType(), VK_LValue)); + PrivateCopies.push_back(buildDeclRefExpr( + *this, VDPrivate, DE->getType(), DE->getExprLoc())); } else { // The variable is also a firstprivate, so initialization sequence // for private copy is generated already. @@ -811,7 +841,7 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, } QualType ExprType = VD->getType().getNonReferenceType(); - ExprResult DE = BuildDeclRefExpr(VD, ExprType, VK_LValue, Id.getLoc()); + ExprResult DE = buildDeclRefExpr(*this, VD, ExprType, Id.getLoc()); return DE; } @@ -2440,10 +2470,7 @@ Expr *OpenMPIterationSpaceChecker::BuildPreCond(Scope *S, Expr *Cond) const { /// \brief Build reference expression to the counter be used for codegen. Expr *OpenMPIterationSpaceChecker::BuildCounterVar() const { - return DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), - GetIncrementSrcRange().getBegin(), Var, - /*RefersToEnclosingVariableOrCapture=*/true, - DefaultLoc, Var->getType(), VK_LValue); + return buildDeclRefExpr(SemaRef, Var, Var->getType(), DefaultLoc); } /// \brief Build initization of the counter be used for codegen. @@ -2624,18 +2651,6 @@ static bool CheckOpenMPIterationSpace( return HasErrors; } -/// \brief Build a variable declaration for OpenMP loop iteration variable. -static VarDecl *BuildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, - StringRef Name) { - DeclContext *DC = SemaRef.CurContext; - IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); - TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); - VarDecl *Decl = - VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); - Decl->setImplicit(); - return Decl; -} - /// \brief Build 'VarRef = Start + Iter * Step'. static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, @@ -2823,10 +2838,10 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, if (!IsConstant) { SourceLocation SaveLoc; VarDecl *SaveVar = - BuildVarDecl(SemaRef, SaveLoc, LastIteration.get()->getType(), + buildVarDecl(SemaRef, SaveLoc, LastIteration.get()->getType(), ".omp.last.iteration"); - ExprResult SaveRef = SemaRef.BuildDeclRefExpr( - SaveVar, LastIteration.get()->getType(), VK_LValue, SaveLoc); + ExprResult SaveRef = buildDeclRefExpr( + SemaRef, SaveVar, LastIteration.get()->getType(), SaveLoc); CalcLastIteration = SemaRef.BuildBinOp(CurScope, SaveLoc, BO_Assign, SaveRef.get(), LastIteration.get()); LastIteration = SaveRef; @@ -2846,15 +2861,15 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, ExprResult LB, UB, IL, ST, EUB; if (isOpenMPWorksharingDirective(DKind)) { // Lower bound variable, initialized with zero. - VarDecl *LBDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); - LB = SemaRef.BuildDeclRefExpr(LBDecl, VType, VK_LValue, InitLoc); + VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); + LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); SemaRef.AddInitializerToDecl( LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), /*DirectInit*/ false, /*TypeMayContainAuto*/ false); // Upper bound variable, initialized with last iteration number. - VarDecl *UBDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); - UB = SemaRef.BuildDeclRefExpr(UBDecl, VType, VK_LValue, InitLoc); + VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); + UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), /*DirectInit*/ false, /*TypeMayContainAuto*/ false); @@ -2862,15 +2877,15 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, // A 32-bit variable-flag where runtime returns 1 for the last iteration. // This will be used to implement clause 'lastprivate'. QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); - VarDecl *ILDecl = BuildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); - IL = SemaRef.BuildDeclRefExpr(ILDecl, Int32Ty, VK_LValue, InitLoc); + VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); + IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); SemaRef.AddInitializerToDecl( ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), /*DirectInit*/ false, /*TypeMayContainAuto*/ false); // Stride variable returned by runtime (we initialize it to 1 by default). - VarDecl *STDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.stride"); - ST = SemaRef.BuildDeclRefExpr(STDecl, VType, VK_LValue, InitLoc); + VarDecl *STDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.stride"); + ST = buildDeclRefExpr(SemaRef, STDecl, VType, InitLoc); SemaRef.AddInitializerToDecl( STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), /*DirectInit*/ false, /*TypeMayContainAuto*/ false); @@ -2890,8 +2905,8 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, ExprResult IV; ExprResult Init; { - VarDecl *IVDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.iv"); - IV = SemaRef.BuildDeclRefExpr(IVDecl, VType, VK_LValue, InitLoc); + VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.iv"); + IV = buildDeclRefExpr(SemaRef, IVDecl, VType, InitLoc); Expr *RHS = isOpenMPWorksharingDirective(DKind) ? LB.get() : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); @@ -2979,9 +2994,13 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, break; } - // Build update: IS.CounterVar = IS.Start + Iter * IS.Step + // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step + auto *CounterVar = buildDeclRefExpr( + SemaRef, cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()), + IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), + /*RefersToCapture=*/true); ExprResult Update = - BuildCounterUpdate(SemaRef, CurScope, UpdLoc, IS.CounterVar, + BuildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, IS.CounterStep, IS.Subtract); if (!Update.isUsable()) { HasErrors = true; @@ -2990,7 +3009,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step ExprResult Final = BuildCounterUpdate( - SemaRef, CurScope, UpdLoc, IS.CounterVar, IS.CounterInit, + SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, IS.NumIterations, IS.CounterStep, IS.Subtract); if (!Final.isUsable()) { HasErrors = true; @@ -4771,20 +4790,14 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, // the new private variable in CodeGen. This new variable is not added to // IdResolver, so the code in the OpenMP region uses original variable for // proper diagnostics. - auto VDPrivate = VarDecl::Create(Context, CurContext, DE->getLocStart(), - DE->getExprLoc(), VD->getIdentifier(), - VD->getType().getUnqualifiedType(), - VD->getTypeSourceInfo(), /*S*/ SC_Auto); - ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto*/ false); + auto VDPrivate = + buildVarDecl(*this, DE->getExprLoc(), + VD->getType().getUnqualifiedType(), VD->getName()); + ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); if (VDPrivate->isInvalidDecl()) continue; - CurContext->addDecl(VDPrivate); auto VDPrivateRefExpr = - DeclRefExpr::Create(Context, /*QualifierLoc*/ NestedNameSpecifierLoc(), - /*TemplateKWLoc*/ SourceLocation(), VDPrivate, - /*RefersToEnclosingVariableOrCapture*/ false, - /*NameLoc*/ SourceLocation(), DE->getType(), - /*VK*/ VK_LValue); + buildDeclRefExpr(*this, VDPrivate, DE->getType(), DE->getExprLoc()); DSAStack->addDSA(VD, DE, OMPC_private); Vars.push_back(DE); @@ -4985,10 +4998,8 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, } } - auto VDPrivate = - VarDecl::Create(Context, CurContext, DE->getLocStart(), ELoc, - VD->getIdentifier(), VD->getType().getUnqualifiedType(), - VD->getTypeSourceInfo(), /*S*/ SC_Auto); + auto VDPrivate = buildVarDecl( + *this, ELoc, VD->getType().getUnqualifiedType(), VD->getName()); // Generate helper private variable and initialize it with the value of the // original variable. The address of the original variable is replaced by // the address of the new private variable in the CodeGen. This new variable @@ -4998,18 +5009,11 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, // For arrays generate initializer for single element and replace it by the // original array element in CodeGen. if (DE->getType()->isArrayType()) { - auto VDInit = VarDecl::Create(Context, CurContext, DE->getLocStart(), - ELoc, VD->getIdentifier(), Type, - VD->getTypeSourceInfo(), /*S*/ SC_Auto); - CurContext->addHiddenDecl(VDInit); - VDInitRefExpr = DeclRefExpr::Create( - Context, /*QualifierLoc*/ NestedNameSpecifierLoc(), - /*TemplateKWLoc*/ SourceLocation(), VDInit, - /*RefersToEnclosingVariableOrCapture*/ true, ELoc, Type, - /*VK*/ VK_LValue); + auto VDInit = buildVarDecl(*this, DE->getExprLoc(), Type, VD->getName()); + VDInitRefExpr = buildDeclRefExpr(*this, VDInit, Type, ELoc); auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); auto *VDInitTemp = - BuildVarDecl(*this, DE->getLocStart(), Type.getUnqualifiedType(), + buildVarDecl(*this, DE->getLocStart(), Type.getUnqualifiedType(), ".firstprivate.temp"); InitializedEntity Entity = InitializedEntity::InitializeVariable(VDInitTemp); @@ -5023,9 +5027,8 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, VDPrivate->setInit(Result.getAs<Expr>()); } else { auto *VDInit = - BuildVarDecl(*this, DE->getLocStart(), Type, ".firstprivate.temp"); - VDInitRefExpr = - BuildDeclRefExpr(VDInit, Type, VK_LValue, DE->getExprLoc()).get(); + buildVarDecl(*this, DE->getLocStart(), Type, ".firstprivate.temp"); + VDInitRefExpr = buildDeclRefExpr(*this, VDInit, Type, DE->getExprLoc()); AddInitializerToDecl(VDPrivate, DefaultLvalueConversion(VDInitRefExpr).get(), /*DirectInit=*/false, /*TypeMayContainAuto=*/false); @@ -5038,11 +5041,8 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, continue; } CurContext->addDecl(VDPrivate); - auto VDPrivateRefExpr = DeclRefExpr::Create( - Context, /*QualifierLoc*/ NestedNameSpecifierLoc(), - /*TemplateKWLoc*/ SourceLocation(), VDPrivate, - /*RefersToEnclosingVariableOrCapture*/ false, DE->getLocStart(), - DE->getType().getUnqualifiedType(), /*VK*/ VK_LValue); + auto VDPrivateRefExpr = buildDeclRefExpr( + *this, VDPrivate, DE->getType().getUnqualifiedType(), DE->getExprLoc()); DSAStack->addDSA(VD, DE, OMPC_firstprivate); Vars.push_back(DE); PrivateCopies.push_back(VDPrivateRefExpr); @@ -5140,6 +5140,7 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, // lastprivate clause on a worksharing construct if any of the corresponding // worksharing regions ever binds to any of the corresponding parallel // regions. + DSAStackTy::DSAVarData TopDVar = DVar; if (isOpenMPWorksharingDirective(CurrDir) && !isOpenMPParallelDirective(CurrDir)) { DVar = DSAStack->getImplicitDSA(VD, true); @@ -5160,14 +5161,14 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, // lastprivate clause requires an accessible, unambiguous copy assignment // operator for the class type. Type = Context.getBaseElementType(Type).getNonReferenceType(); - auto *SrcVD = BuildVarDecl(*this, DE->getLocStart(), + auto *SrcVD = buildVarDecl(*this, DE->getLocStart(), Type.getUnqualifiedType(), ".lastprivate.src"); - auto *PseudoSrcExpr = BuildDeclRefExpr(SrcVD, Type.getUnqualifiedType(), - VK_LValue, DE->getExprLoc()).get(); + auto *PseudoSrcExpr = buildDeclRefExpr( + *this, SrcVD, Type.getUnqualifiedType(), DE->getExprLoc()); auto *DstVD = - BuildVarDecl(*this, DE->getLocStart(), Type, ".lastprivate.dst"); + buildVarDecl(*this, DE->getLocStart(), Type, ".lastprivate.dst"); auto *PseudoDstExpr = - BuildDeclRefExpr(DstVD, Type, VK_LValue, DE->getExprLoc()).get(); + buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc()); // For arrays generate assignment operation for single element and replace // it by the original array element in CodeGen. auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, @@ -5179,7 +5180,7 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, if (AssignmentOp.isInvalid()) continue; - if (DVar.CKind != OMPC_firstprivate) + if (TopDVar.CKind != OMPC_firstprivate) DSAStack->addDSA(VD, DE, OMPC_lastprivate); Vars.push_back(DE); SrcExprs.push_back(PseudoSrcExpr); @@ -5547,8 +5548,8 @@ OMPClause *Sema::ActOnOpenMPReductionClause( } } Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); - auto *LHSVD = BuildVarDecl(*this, ELoc, Type, ".reduction.lhs"); - auto *RHSVD = BuildVarDecl(*this, ELoc, Type, VD->getName()); + auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs"); + auto *RHSVD = buildVarDecl(*this, ELoc, Type, VD->getName()); // Add initializer for private variable. Expr *Init = nullptr; switch (BOK) { @@ -5670,8 +5671,8 @@ OMPClause *Sema::ActOnOpenMPReductionClause( << VD; continue; } - auto *LHSDRE = BuildDeclRefExpr(LHSVD, Type, VK_LValue, ELoc).get(); - auto *RHSDRE = BuildDeclRefExpr(RHSVD, Type, VK_LValue, ELoc).get(); + auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc); + auto *RHSDRE = buildDeclRefExpr(*this, RHSVD, Type, ELoc); ExprResult ReductionOp = BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE); @@ -5812,16 +5813,11 @@ OMPClause *Sema::ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step, } // Build var to save initial value. - VarDecl *Init = BuildVarDecl(*this, ELoc, DE->getType(), ".linear.start"); + VarDecl *Init = buildVarDecl(*this, ELoc, DE->getType(), ".linear.start"); AddInitializerToDecl(Init, DefaultLvalueConversion(DE).get(), /*DirectInit*/ false, /*TypeMayContainAuto*/ false); - CurContext->addDecl(Init); - Init->setIsUsed(); - auto InitRef = DeclRefExpr::Create( - Context, /*QualifierLoc*/ NestedNameSpecifierLoc(), - /*TemplateKWLoc*/ SourceLocation(), Init, - /*isEnclosingLocal*/ false, DE->getLocStart(), DE->getType(), - /*VK*/ VK_LValue); + auto InitRef = + buildDeclRefExpr(*this, Init, DE->getType(), DE->getExprLoc()); DSAStack->addDSA(VD, DE, OMPC_linear); Vars.push_back(DE); Inits.push_back(InitRef); @@ -5843,11 +5839,9 @@ OMPClause *Sema::ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step, // Build var to save the step value. VarDecl *SaveVar = - BuildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); - CurContext->addDecl(SaveVar); - SaveVar->setIsUsed(); + buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); ExprResult SaveRef = - BuildDeclRefExpr(SaveVar, StepExpr->getType(), VK_LValue, StepLoc); + buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); ExprResult CalcStep = BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); @@ -5890,11 +5884,9 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, // Build privatized reference to the current linear var. auto DE = cast<DeclRefExpr>(RefExpr); - auto PrivateRef = DeclRefExpr::Create( - SemaRef.Context, /*QualifierLoc*/ DE->getQualifierLoc(), - /*TemplateKWLoc*/ SourceLocation(), DE->getDecl(), - /* RefersToEnclosingVariableOrCapture */ true, DE->getLocStart(), - DE->getType(), /*VK*/ VK_LValue); + auto PrivateRef = + buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), DE->getType(), + DE->getExprLoc(), /*RefersToCapture=*/true); // Build update: Var = InitExpr + IV * Step ExprResult Update = @@ -5904,8 +5896,8 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, // Build final: Var = InitExpr + NumIterations * Step ExprResult Final = - BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), RefExpr, InitExpr, - NumIterations, Step, /* Subtract */ false); + BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), PrivateRef, + InitExpr, NumIterations, Step, /* Subtract */ false); Final = SemaRef.ActOnFinishFullExpr(Final.get()); if (!Update.isUsable() || !Final.isUsable()) { Updates.push_back(nullptr); @@ -6054,14 +6046,13 @@ OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, // copyin clause requires an accessible, unambiguous copy assignment // operator for the class type. Type = Context.getBaseElementType(Type).getNonReferenceType(); - auto *SrcVD = BuildVarDecl(*this, DE->getLocStart(), + auto *SrcVD = buildVarDecl(*this, DE->getLocStart(), Type.getUnqualifiedType(), ".copyin.src"); - auto *PseudoSrcExpr = BuildDeclRefExpr(SrcVD, Type.getUnqualifiedType(), - VK_LValue, DE->getExprLoc()) - .get(); - auto *DstVD = BuildVarDecl(*this, DE->getLocStart(), Type, ".copyin.dst"); + auto *PseudoSrcExpr = buildDeclRefExpr( + *this, SrcVD, Type.getUnqualifiedType(), DE->getExprLoc()); + auto *DstVD = buildVarDecl(*this, DE->getLocStart(), Type, ".copyin.dst"); auto *PseudoDstExpr = - BuildDeclRefExpr(DstVD, Type, VK_LValue, DE->getExprLoc()).get(); + buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc()); // For arrays generate assignment operation for single element and replace // it by the original array element in CodeGen. auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, @@ -6165,13 +6156,13 @@ OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, // operator for the class type. Type = Context.getBaseElementType(Type).getUnqualifiedType(); auto *SrcVD = - BuildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.src"); + buildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.src"); auto *PseudoSrcExpr = - BuildDeclRefExpr(SrcVD, Type, VK_LValue, DE->getExprLoc()).get(); + buildDeclRefExpr(*this, SrcVD, Type, DE->getExprLoc()); auto *DstVD = - BuildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.dst"); + buildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.dst"); auto *PseudoDstExpr = - BuildDeclRefExpr(DstVD, Type, VK_LValue, DE->getExprLoc()).get(); + buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc()); auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, PseudoSrcExpr); if (AssignmentOp.isInvalid()) diff --git a/test/OpenMP/for_lastprivate_codegen.cpp b/test/OpenMP/for_lastprivate_codegen.cpp index 7d3337a255317c6f10c840280abaccb95829768e..3aee293ecb6df1b4731feddd64b401aac63354f5 100644 --- a/test/OpenMP/for_lastprivate_codegen.cpp +++ b/test/OpenMP/for_lastprivate_codegen.cpp @@ -18,6 +18,7 @@ struct S { }; volatile int g = 1212; +float f; // CHECK: [[S_FLOAT_TY:%.+]] = type { float } // CHECK: [[CAP_MAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* } @@ -25,6 +26,7 @@ volatile int g = 1212; // CHECK: [[CAP_TMAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } // CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* // CHECK-DAG: [[X:@.+]] = global double 0.0 +// CHECK-DAG: [[F:@.+]] = global float 0.0 template <typename T> T tmain() { S<T> test; @@ -167,7 +169,7 @@ int main() { s_arr[i] = var; } #pragma omp parallel -#pragma omp for lastprivate(A::x, B::x) +#pragma omp for lastprivate(A::x, B::x) firstprivate(f) lastprivate(f) for (int i = 0; i < 2; ++i) { A::x++; } @@ -255,11 +257,17 @@ int main() { // // CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: [[F_PRIV:%.+]] = alloca float, +// CHECK-NOT: alloca float // CHECK: [[X_PRIV:%.+]] = alloca double, +// CHECK-NOT: alloca float // CHECK-NOT: alloca double // Check for default initialization. // CHECK-NOT: [[X_PRIV]] +// CHECK: [[F_VAL:%.+]] = load float, float* [[F]], +// CHECK: store float [[F_VAL]], float* [[F_PRIV]], +// CHECK-NOT: [[X_PRIV]] // CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]] // CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] @@ -277,6 +285,11 @@ int main() { // original x=private_x; // CHECK: [[X_VAL:%.+]] = load double, double* [[X_PRIV]], // CHECK: store double [[X_VAL]], double* [[X]], + +// original f=private_f; +// CHECK: [[F_VAL:%.+]] = load float, float* [[F_PRIV]], +// CHECK: store float [[F_VAL]], float* [[F]], + // CHECK-NEXT: br label %[[LAST_DONE]] // CHECK: [[LAST_DONE]]