r236821 - [OPENMP] Code cleanup for capturing of variables in OpenMP regions.

Alexey Bataev a.bataev at hotmail.com
Fri May 8 03:41:22 PDT 2015


Author: abataev
Date: Fri May  8 05:41:21 2015
New Revision: 236821

URL: http://llvm.org/viewvc/llvm-project?rev=236821&view=rev
Log:
[OPENMP] Code cleanup for capturing of variables in OpenMP regions.


Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
    cfe/trunk/lib/Parse/ParseOpenMP.cpp
    cfe/trunk/lib/Sema/SemaOpenMP.cpp
    cfe/trunk/test/OpenMP/for_lastprivate_codegen.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=236821&r1=236820&r2=236821&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri May  8 05:41:21 2015
@@ -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);
 

Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=236821&r1=236820&r2=236821&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Fri May  8 05:41:21 2015
@@ -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(c
   // 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;
     }
   }
 }

Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=236821&r1=236820&r2=236821&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
+++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Fri May  8 05:41:21 2015
@@ -223,6 +223,7 @@ Parser::ParseOpenMPDeclarativeOrExecutab
     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::ParseOpenMPDeclarativeOrExecutab
       if (Tok.is(tok::comma))
         ConsumeToken();
     }
+    Actions.EndOpenMPClauses();
     // End location of the directive.
     EndLoc = Tok.getLocation();
     // Consume final annot_pragma_openmp_end.

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=236821&r1=236820&r2=236821&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Fri May  8 05:41:21 2015
@@ -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 *
   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::getTo
   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 *
   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(OpenMPDir
   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 *CurDi
             // 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
   }
 
   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::Build
 
 /// \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 DKin
   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 DKin
   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 DKin
     // 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 DKin
   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 DKin
         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 DKin
 
       // 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::ActOnOpenMPPrivateClaus
     // 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::ActOnOpenMPFirstprivate
       }
     }
 
-    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::ActOnOpenMPFirstprivate
     // 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::ActOnOpenMPFirstprivate
         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::ActOnOpenMPFirstprivate
       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::ActOnOpenMPLastprivateC
     // 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::ActOnOpenMPLastprivateC
     //  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::ActOnOpenMPLastprivateC
     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::ActOnOpenMPReductionCla
       }
     }
     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::ActOnOpenMPReductionCla
           << 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
     }
 
     // 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
 
     // 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(OMP
 
     // 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(OMP
 
     // 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
     //  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::ActOnOpenMPCopyprivateC
     //  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())

Modified: cfe/trunk/test/OpenMP/for_lastprivate_codegen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_lastprivate_codegen.cpp?rev=236821&r1=236820&r2=236821&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/for_lastprivate_codegen.cpp (original)
+++ cfe/trunk/test/OpenMP/for_lastprivate_codegen.cpp Fri May  8 05:41:21 2015
@@ -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]]
 





More information about the cfe-commits mailing list